From 182792d6cffc3e6425b1bbabcc1e77b06be2f661 Mon Sep 17 00:00:00 2001 From: Kawika Avilla Date: Mon, 26 Aug 2024 04:29:24 +0000 Subject: [PATCH] Metadata slice Signed-off-by: Kawika Avilla --- src/plugins/data/common/datasets/types.ts | 9 +---- .../index_patterns/index_patterns.ts | 1 + .../dataset_service/lib/index_pattern_type.ts | 13 +++---- .../query_string/query_string_manager.ts | 11 ++---- .../data/public/ui/dataset_selector/index.tsx | 6 +-- .../lib/use_query_string_manager.ts | 11 +++--- .../utils/state_management/metadata_slice.ts | 9 +---- .../state_management/redux_persistence.ts | 37 ++++++++++++++++++- .../public/utils/state_management/store.ts | 2 +- .../utils/state_management/index.ts | 3 +- .../view_components/canvas/index.tsx | 10 +---- 11 files changed, 60 insertions(+), 52 deletions(-) diff --git a/src/plugins/data/common/datasets/types.ts b/src/plugins/data/common/datasets/types.ts index 9f6105cdb22b..ae50326ead61 100644 --- a/src/plugins/data/common/datasets/types.ts +++ b/src/plugins/data/common/datasets/types.ts @@ -202,7 +202,6 @@ export interface BaseDataset { type: string; /** Optional reference to the data source */ dataSource?: DataSource; - fields?: DatasetField[]; } /** @@ -213,16 +212,12 @@ export interface BaseDataset { * * @example * Example of a Dataset for an OpenSearch index pattern + * Index patterns have a reference to the data source and their title is pre appended with the data source they belong to so we dont need to append the data source to the dataset object * const logsIndexDataset: Dataset = { * id: "2e1b1b80-9c4d-11ee-8c90-0242ac120001", - * title: "logs-*", + * title: "Cluster1::logs-*", * type: "INDEX_PATTERN", * timeFieldName: "@timestamp", - * dataSource: { - * id: "main-cluster", - * title: "Main OpenSearch Cluster", - * type: "OPENSEARCH" - * }, * }; * * @example diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index 3d0dbe15dab7..ccda27870313 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -122,6 +122,7 @@ export class IndexPatternsService { this.savedObjectsCache = await Promise.all( this.savedObjectsCache.map(async (obj) => { + // TODO: This behaviour will cause the index pattern title to be resolved differently depending on how its fetched since the get method in this service will not append the datasource title if (obj.type === 'index-pattern') { const result = { ...obj }; result.attributes.title = await getIndexPatternTitle( diff --git a/src/plugins/data/public/query/query_string/dataset_service/lib/index_pattern_type.ts b/src/plugins/data/public/query/query_string/dataset_service/lib/index_pattern_type.ts index c5f44445695d..5fc81fe95e8f 100644 --- a/src/plugins/data/public/query/query_string/dataset_service/lib/index_pattern_type.ts +++ b/src/plugins/data/public/query/query_string/dataset_service/lib/index_pattern_type.ts @@ -60,14 +60,11 @@ export const indexPatternTypeConfig: DatasetTypeConfig = { }; const fetchIndexPatterns = async (client: SavedObjectsClientContract): Promise => { - const resp = await client.find({ - type: 'index-pattern', - fields: ['title'], - perPage: 10000, - }); - return resp.savedObjects.map((savedObject) => ({ - id: savedObject.id, - title: savedObject.attributes.title, + const indexPatterns = await getIndexPatterns().getIdsWithTitle(); + + return indexPatterns.map((indexPattern) => ({ + id: indexPattern.id, + title: indexPattern.title, type: DEFAULT_DATA.SET_TYPES.INDEX_PATTERN, })); }; diff --git a/src/plugins/data/public/query/query_string/query_string_manager.ts b/src/plugins/data/public/query/query_string/query_string_manager.ts index c9b11aa5158b..38bab9a8132c 100644 --- a/src/plugins/data/public/query/query_string/query_string_manager.ts +++ b/src/plugins/data/public/query/query_string/query_string_manager.ts @@ -95,15 +95,10 @@ export class QueryStringManager { * Updates the query. * @param {Query} query */ - public setQuery = (query: Query) => { + public setQuery = (query: Partial) => { const curQuery = this.query$.getValue(); - if ( - query?.language !== curQuery.language || - query?.query !== curQuery.query || - query?.dataset !== curQuery.dataset - ) { - this.query$.next(query); - } + const newQuery = { ...curQuery, ...query }; + this.query$.next(newQuery); }; /** diff --git a/src/plugins/data/public/ui/dataset_selector/index.tsx b/src/plugins/data/public/ui/dataset_selector/index.tsx index 720cf6cd642a..c5c2835fe6ef 100644 --- a/src/plugins/data/public/ui/dataset_selector/index.tsx +++ b/src/plugins/data/public/ui/dataset_selector/index.tsx @@ -15,14 +15,12 @@ interface ConnectedDatasetSelectorProps { } const ConnectedDatasetSelector = ({ onSubmit }: ConnectedDatasetSelectorProps) => { - const [selectedDataset, setSelectedDataset] = useState(); const { services } = useOpenSearchDashboards(); const queryString = services.data.query.queryString; + const initialDataset = queryString.getQuery().dataset || queryString.getDefaultQuery().dataset; + const [selectedDataset, setSelectedDataset] = useState(initialDataset); useEffect(() => { - const initialDataset = queryString.getQuery().dataset || queryString.getDefaultQuery().dataset; - setSelectedDataset(initialDataset); - const subscription = queryString.getUpdates$().subscribe((query) => { setSelectedDataset(query.dataset); }); diff --git a/src/plugins/data/public/ui/search_bar/lib/use_query_string_manager.ts b/src/plugins/data/public/ui/search_bar/lib/use_query_string_manager.ts index 21dda3d3f309..8f9d49f80fef 100644 --- a/src/plugins/data/public/ui/search_bar/lib/use_query_string_manager.ts +++ b/src/plugins/data/public/ui/search_bar/lib/use_query_string_manager.ts @@ -58,15 +58,16 @@ export const useQueryStringManager = (props: UseQueryStringProps) => { return () => { subscriptions.unsubscribe(); }; - }, [props.queryString]); // Remove query from dependencies + }, [props.queryString]); // Use callback to memoize the function const updateQuery = useCallback( - (newQuery) => { - props.queryString.setQuery(newQuery); - setQuery(newQuery); + (newQueryPartial: Partial) => { + const updatedQuery = { ...query, ...newQueryPartial }; + props.queryString.setQuery(updatedQuery); + setQuery(updatedQuery); }, - [props.queryString] + [query, props.queryString] ); return { diff --git a/src/plugins/data_explorer/public/utils/state_management/metadata_slice.ts b/src/plugins/data_explorer/public/utils/state_management/metadata_slice.ts index 70fb0b77c47c..b0965869c336 100644 --- a/src/plugins/data_explorer/public/utils/state_management/metadata_slice.ts +++ b/src/plugins/data_explorer/public/utils/state_management/metadata_slice.ts @@ -5,13 +5,11 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { DataExplorerServices } from '../../types'; -import { Dataset } from '../../../../data/common'; export interface MetadataState { indexPattern?: string; originatingApp?: string; view?: string; - dataSet?: Omit; } const initialState: MetadataState = {}; @@ -39,12 +37,9 @@ export const slice = createSlice({ name: 'metadata', initialState, reducers: { - setIndexPattern: (state, action: PayloadAction) => { + setIndexPattern: (state, action: PayloadAction) => { state.indexPattern = action.payload; }, - setDataSet: (state, action: PayloadAction>) => { - state.dataSet = action.payload; - }, setOriginatingApp: (state, action: PayloadAction) => { state.originatingApp = action.payload; }, @@ -58,4 +53,4 @@ export const slice = createSlice({ }); export const { reducer } = slice; -export const { setIndexPattern, setDataSet, setOriginatingApp, setView, setState } = slice.actions; +export const { setIndexPattern, setOriginatingApp, setView, setState } = slice.actions; diff --git a/src/plugins/data_explorer/public/utils/state_management/redux_persistence.ts b/src/plugins/data_explorer/public/utils/state_management/redux_persistence.ts index 81517f3e9f4f..a6a7d29156d3 100644 --- a/src/plugins/data_explorer/public/utils/state_management/redux_persistence.ts +++ b/src/plugins/data_explorer/public/utils/state_management/redux_persistence.ts @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { DEFAULT_DATA } from '../../../../data/common'; +import { QUERY_ENHANCEMENT_ENABLED_SETTING } from '../../components/constants'; import { DataExplorerServices } from '../../types'; import { getPreloadedState } from './preload'; import { RootState } from './store'; @@ -10,7 +12,40 @@ import { RootState } from './store'; export const loadReduxState = async (services: DataExplorerServices) => { try { const serializedState = services.osdUrlStateStorage.get('_a'); - if (serializedState !== null) return serializedState; + if (serializedState !== null) { + const isQueryEnhancementEnabled = services.uiSettings.get(QUERY_ENHANCEMENT_ENABLED_SETTING); + + // Migrate index pattern to query state + if (isQueryEnhancementEnabled && serializedState.metadata.indexPattern) { + const indexPattern = await services.data.indexPatterns.get( + serializedState.metadata.indexPattern + ); + + const dataset = { + id: serializedState.metadata.indexPattern, + title: indexPattern.title, + type: DEFAULT_DATA.SET_TYPES.INDEX_PATTERN, + }; + + // TODO: This is a temporary fix since indexpattern.get does not modify the title like the other list based methods. This should be handeled in a better way: https://github.com/opensearch-project/OpenSearch-Dashboards/issues/7837 + if (indexPattern.dataSourceRef) { + const dataSource = await services.data.indexPatterns.getDataSource( + indexPattern.dataSourceRef.id + ); + + if (dataSource) { + dataset.title = `${dataSource.attributes.title}::${dataset.title}`; + } + } + services.data.query.queryString.setQuery({ + dataset, + }); + + delete serializedState.metadata.indexPattern; + } + + return serializedState; + } } catch (err) { // eslint-disable-next-line no-console console.error(err); diff --git a/src/plugins/data_explorer/public/utils/state_management/store.ts b/src/plugins/data_explorer/public/utils/state_management/store.ts index 9d320de4b54b..daf0b3d7e369 100644 --- a/src/plugins/data_explorer/public/utils/state_management/store.ts +++ b/src/plugins/data_explorer/public/utils/state_management/store.ts @@ -116,4 +116,4 @@ export type RenderState = Omit; // Remaining state after export type Store = ReturnType; export type AppDispatch = Store['dispatch']; -export { MetadataState, setIndexPattern, setDataSet, setOriginatingApp } from './metadata_slice'; +export { MetadataState, setIndexPattern, setOriginatingApp } from './metadata_slice'; diff --git a/src/plugins/discover/public/application/utils/state_management/index.ts b/src/plugins/discover/public/application/utils/state_management/index.ts index e6df7e4774b8..989b2662f0d4 100644 --- a/src/plugins/discover/public/application/utils/state_management/index.ts +++ b/src/plugins/discover/public/application/utils/state_management/index.ts @@ -7,7 +7,6 @@ import { TypedUseSelectorHook } from 'react-redux'; import { RootState, setIndexPattern as updateIndexPattern, - setDataSet as updateDataSet, useTypedDispatch, useTypedSelector, } from '../../../../../data_explorer/public'; @@ -21,4 +20,4 @@ export interface DiscoverRootState extends RootState { export const useSelector: TypedUseSelectorHook = useTypedSelector; export const useDispatch = useTypedDispatch; -export { updateIndexPattern, updateDataSet }; +export { updateIndexPattern }; diff --git a/src/plugins/discover/public/application/view_components/canvas/index.tsx b/src/plugins/discover/public/application/view_components/canvas/index.tsx index 500c8ebdc80c..a44ac89c5d62 100644 --- a/src/plugins/discover/public/application/view_components/canvas/index.tsx +++ b/src/plugins/discover/public/application/view_components/canvas/index.tsx @@ -3,15 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { i18n } from '@osd/i18n'; import React, { useEffect, useState, useRef, useCallback } from 'react'; -import { - EuiButtonIcon, - EuiContextMenu, - EuiPanel, - EuiPopover, - EuiCompressedSwitch, -} from '@elastic/eui'; +import { EuiPanel } from '@elastic/eui'; import { TopNav } from './top_nav'; import { ViewProps } from '../../../../../data_explorer/public'; import { DiscoverTable } from './discover_table'; @@ -33,7 +26,6 @@ import { import { OpenSearchSearchHit } from '../../../application/doc_views/doc_views_types'; import { buildColumns } from '../../utils/columns'; import './discover_canvas.scss'; -import { getNewDiscoverSetting, setNewDiscoverSetting } from '../../components/utils/local_storage'; import { HeaderVariant } from '../../../../../../core/public'; // eslint-disable-next-line import/no-default-export