diff --git a/CHANGELOG.md b/CHANGELOG.md index 8330075b7173..a9210c679f17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [BUG][Data Explorer][Discover] Add onQuerySubmit to top nav and allow force update to embeddable ([#5160](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5160)) - [BUG][Discover] Fix misc navigation issues ([#5168](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5168)) - [BUG][Discover] Fix mobile view ([#5168](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5168)) +- [BUG][Data Explorer][Discover] Automatically load solo added default index pattern ([#5171](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5171)) ### 🚞 Infrastructure diff --git a/src/plugins/data_explorer/public/index.ts b/src/plugins/data_explorer/public/index.ts index 635a0ec285db..cb33d2b7d90c 100644 --- a/src/plugins/data_explorer/public/index.ts +++ b/src/plugins/data_explorer/public/index.ts @@ -14,4 +14,10 @@ export function plugin() { } export { DataExplorerPluginSetup, DataExplorerPluginStart, DataExplorerServices } from './types'; export { ViewProps, ViewDefinition, DefaultViewState } from './services/view_service'; -export { RootState, useTypedSelector, useTypedDispatch } from './utils/state_management'; +export { + RootState, + Store, + useTypedSelector, + useTypedDispatch, + setIndexPattern, +} from './utils/state_management'; 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 d72cc772e6c4..9e0d5bc64ffd 100644 --- a/src/plugins/discover/public/application/utils/state_management/index.ts +++ b/src/plugins/discover/public/application/utils/state_management/index.ts @@ -4,7 +4,13 @@ */ import { TypedUseSelectorHook } from 'react-redux'; -import { RootState, useTypedDispatch, useTypedSelector } from '../../../../../data_explorer/public'; +import { + RootState, + Store as StoreType, + setIndexPattern as updateIndexPattern, + useTypedDispatch, + useTypedSelector, +} from '../../../../../data_explorer/public'; import { DiscoverState } from './discover_slice'; export * from './discover_slice'; @@ -15,3 +21,4 @@ export interface DiscoverRootState extends RootState { export const useSelector: TypedUseSelectorHook = useTypedSelector; export const useDispatch = useTypedDispatch; +export { StoreType, updateIndexPattern }; diff --git a/src/plugins/discover/public/application/view_components/canvas/discover_table.tsx b/src/plugins/discover/public/application/view_components/canvas/discover_table.tsx index 3cdf48a30dfc..e57a0b7c7668 100644 --- a/src/plugins/discover/public/application/view_components/canvas/discover_table.tsx +++ b/src/plugins/discover/public/application/view_components/canvas/discover_table.tsx @@ -35,7 +35,7 @@ export const DiscoverTable = ({ history }: Props) => { query: { filterManager }, }, } = services; - const { data$, refetch$, indexPattern } = useDiscoverContext(); + const { data$, refetch$, indexPattern, savedSearch } = useDiscoverContext(); const [fetchState, setFetchState] = useState({ status: data$.getValue().status, rows: [], @@ -71,7 +71,6 @@ export const DiscoverTable = ({ history }: Props) => { ); const { rows } = fetchState || {}; - const { savedSearch } = useSearch(services); useEffect(() => { const subscription = data$.subscribe((next) => { diff --git a/src/plugins/discover/public/application/view_components/utils/use_index_pattern.ts b/src/plugins/discover/public/application/view_components/utils/use_index_pattern.ts index 872639107987..10a795abac37 100644 --- a/src/plugins/discover/public/application/view_components/utils/use_index_pattern.ts +++ b/src/plugins/discover/public/application/view_components/utils/use_index_pattern.ts @@ -6,46 +6,72 @@ import { useEffect, useState } from 'react'; import { i18n } from '@osd/i18n'; import { IndexPattern } from '../../../../../data/public'; -import { useSelector } from '../../utils/state_management'; +import { useSelector, updateIndexPattern, StoreType } from '../../utils/state_management'; import { DiscoverServices } from '../../../build_services'; +import { getIndexPatternId } from '../../helpers/get_index_pattern_id'; -export const useIndexPattern = (services: DiscoverServices) => { - const indexPatternId = useSelector((state) => state.metadata.indexPattern); +/** + * Custom hook to fetch and manage the index pattern based on the provided services. + * + * This hook does the following: + * 1. Check if there's an `indexPatternId` from the state. + * 2. If not, fetch a list of index patterns, determine the default, and update the store with it. + * 3. Once an `indexPatternId` is determined (either from the state or by fetching the default), + * it fetches the details of the index pattern. + * 4. If there's any error fetching the index pattern details, a warning notification is shown. + * + * @param services - The services needed to fetch the index patterns and show notifications. + * @param store - The redux store in data_explorer to dispatch actions. + * @returns - The fetched index pattern. + */ +export const useIndexPattern = (services: DiscoverServices, store: StoreType) => { + const indexPatternIdFromState = useSelector((state) => state.metadata.indexPattern); const [indexPattern, setIndexPattern] = useState(undefined); - const { data, toastNotifications } = services; + const { data, toastNotifications, uiSettings: config } = services; useEffect(() => { let isMounted = true; - if (!indexPatternId) return; - const indexPatternMissingWarning = i18n.translate( - 'discover.valueIsNotConfiguredIndexPatternIDWarningTitle', - { - defaultMessage: '{id} is not a configured index pattern ID', - values: { - id: `"${indexPatternId}"`, - }, - } - ); - data.indexPatterns - .get(indexPatternId) - .then((result) => { - if (isMounted) { - setIndexPattern(result); - } - }) - .catch(() => { - if (isMounted) { - toastNotifications.addDanger({ - title: indexPatternMissingWarning, - }); - } + const fetchIndexPatternDetails = (id: string) => { + data.indexPatterns + .get(id) + .then((result) => { + if (isMounted) { + setIndexPattern(result); + } + }) + .catch(() => { + if (isMounted) { + const indexPatternMissingWarning = i18n.translate( + 'discover.valueIsNotConfiguredIndexPatternIDWarningTitle', + { + defaultMessage: '{id} is not a configured index pattern ID', + values: { + id: `"${id}"`, + }, + } + ); + toastNotifications.addDanger({ + title: indexPatternMissingWarning, + }); + } + }); + }; + + if (!indexPatternIdFromState) { + data.indexPatterns.getCache().then((indexPatternList) => { + const newId = getIndexPatternId('', indexPatternList, config.get('defaultIndex')); + store!.dispatch(updateIndexPattern(newId)); + fetchIndexPatternDetails(newId); }); + } else { + fetchIndexPatternDetails(indexPatternIdFromState); + } return () => { isMounted = false; }; - }, [indexPatternId, data.indexPatterns, toastNotifications]); + }, [indexPatternIdFromState, data.indexPatterns, toastNotifications, config, store]); return indexPattern; }; diff --git a/src/plugins/discover/public/application/view_components/utils/use_search.ts b/src/plugins/discover/public/application/view_components/utils/use_search.ts index 4066d0063a3a..d8c25e1a98e7 100644 --- a/src/plugins/discover/public/application/view_components/utils/use_search.ts +++ b/src/plugins/discover/public/application/view_components/utils/use_search.ts @@ -70,8 +70,8 @@ export const useSearch = (services: DiscoverViewServices) => { const initalSearchComplete = useRef(false); const [savedSearch, setSavedSearch] = useState(undefined); const { savedSearch: savedSearchId, sort, interval } = useSelector((state) => state.discover); - const indexPattern = useIndexPattern(services); - const { data, filterManager, getSavedSearchById, core, toastNotifications } = services; + const { data, filterManager, getSavedSearchById, core, toastNotifications, store } = services; + const indexPattern = useIndexPattern(services, store); const timefilter = data.query.timefilter.timefilter; const fetchStateRef = useRef<{ abortController: AbortController | undefined;