From 16b5cf88e51155a2d95da7023ba49dec11a58a67 Mon Sep 17 00:00:00 2001 From: ananzh Date: Thu, 31 Aug 2023 15:52:51 +0000 Subject: [PATCH] [Data Explorer][Discover 2.0] Fix issues when change index pattern * allow side nav show only selected index pattern fields when switch * allow reset column state when switch index pattern Issue Resolve: https://github.com/opensearch-project/OpenSearch-Dashboards/issues/4840 https://github.com/opensearch-project/OpenSearch-Dashboards/issues/4846 Signed-off-by: ananzh --- .../lib/get_index_pattern_field_list.ts | 15 +------- .../view_components/canvas/index.tsx | 25 +++++++++++++- .../utils/filter_columns.test.ts | 34 +++++++++++++++++++ .../view_components/utils/filter_columns.ts | 25 ++++++++++++++ 4 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 src/plugins/discover/public/application/view_components/utils/filter_columns.test.ts create mode 100644 src/plugins/discover/public/application/view_components/utils/filter_columns.ts diff --git a/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts b/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts index b3a8ff5cd8d9..93b80ae99653 100644 --- a/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts +++ b/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts @@ -36,18 +36,5 @@ export function getIndexPatternFieldList( fieldCounts?: Record ) { if (!indexPattern || !fieldCounts) return []; - - const fieldNamesInDocs = Object.keys(fieldCounts); - const fieldNamesInIndexPattern = indexPattern.fields.getAll().map((fld) => fld.name); - const unknownTypes: IndexPatternField[] = []; - - difference(fieldNamesInDocs, fieldNamesInIndexPattern).forEach((unknownFieldName) => { - unknownTypes.push({ - displayName: String(unknownFieldName), - name: String(unknownFieldName), - type: 'unknown', - } as IndexPatternField); - }); - - return [...indexPattern.fields.getAll(), ...unknownTypes]; + return [...indexPattern.fields.getAll()]; } 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 78f734569837..68196dc3ce2c 100644 --- a/src/plugins/discover/public/application/view_components/canvas/index.tsx +++ b/src/plugins/discover/public/application/view_components/canvas/index.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useMemo, useRef } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiCallOut, EuiLink } from '@elastic/eui'; import { TopNav } from './top_nav'; import { ViewProps } from '../../../../../data_explorer/public'; @@ -14,10 +14,26 @@ import { ResultStatus, SearchData } from '../utils/use_search'; import { DiscoverNoResults } from '../../components/no_results/no_results'; import { DiscoverUninitialized } from '../../components/uninitialized/uninitialized'; import { LoadingSpinner } from '../../components/loading_spinner/loading_spinner'; +import { setColumns, useDispatch, useSelector } from '../../utils/state_management'; +import { DiscoverViewServices } from '../../../build_services'; +import { useOpenSearchDashboards } from '../../../../../opensearch_dashboards_react/public'; +import { filterColumns } from '../utils/filter_columns'; +import { DEFAULT_COLUMNS_SETTING } from '../../../../common'; // eslint-disable-next-line import/no-default-export export default function DiscoverCanvas({ setHeaderActionMenu, history }: ViewProps) { const { data$, refetch$, indexPattern } = useDiscoverContext(); + const { + services: { uiSettings }, + } = useOpenSearchDashboards(); + const { columns } = useSelector((state) => state.discover); + const filteredColumns = filterColumns( + columns, + indexPattern, + uiSettings.get(DEFAULT_COLUMNS_SETTING) + ); + const dispatch = useDispatch(); + const prevIndexPattern = useRef(indexPattern); const [fetchState, setFetchState] = useState({ status: data$.getValue().status, @@ -69,6 +85,13 @@ export default function DiscoverCanvas({ setHeaderActionMenu, history }: ViewPro }; }, [data$, fetchState]); + useEffect(() => { + if (indexPattern !== prevIndexPattern.current) { + dispatch(setColumns({ columns: filteredColumns })); + prevIndexPattern.current = indexPattern; + } + }, [dispatch, filteredColumns, indexPattern]); + const timeField = indexPattern?.timeFieldName ? indexPattern.timeFieldName : undefined; return ( diff --git a/src/plugins/discover/public/application/view_components/utils/filter_columns.test.ts b/src/plugins/discover/public/application/view_components/utils/filter_columns.test.ts new file mode 100644 index 000000000000..5ab22f5fa363 --- /dev/null +++ b/src/plugins/discover/public/application/view_components/utils/filter_columns.test.ts @@ -0,0 +1,34 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { filterColumns } from './filter_columns'; +import { IndexPattern } from '../../../opensearch_dashboards_services'; + +describe('filterColumns', () => { + const indexPatternMock = { + fields: { + getAll: () => [{ name: 'a' }, { name: 'c' }, { name: 'd' }], + }, + } as IndexPattern; + const defaultColumns = ['_defaultColumn']; + + it('should return columns that exist in the index pattern fields', () => { + const columns = ['a', 'b']; + const result = filterColumns(columns, indexPatternMock, defaultColumns); + expect(result).toEqual(['a']); + }); + + it('should return defaultColumns if no columns exist in the index pattern fields', () => { + const columns = ['b', 'e']; + const result = filterColumns(columns, indexPatternMock, defaultColumns); + expect(result).toEqual(defaultColumns); + }); + + it('should return defaultColumns if no columns and indexPattern is null', () => { + const columns = ['b', 'e']; + const result = filterColumns(columns, null, defaultColumns); + expect(result).toEqual(defaultColumns); + }); +}); diff --git a/src/plugins/discover/public/application/view_components/utils/filter_columns.ts b/src/plugins/discover/public/application/view_components/utils/filter_columns.ts new file mode 100644 index 000000000000..47c0921ddf3a --- /dev/null +++ b/src/plugins/discover/public/application/view_components/utils/filter_columns.ts @@ -0,0 +1,25 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { IndexPattern } from '../../../opensearch_dashboards_services'; + +/** + * Helper function to filter columns based on the fields of the index pattern. + * This function is used when we switch between index patterns. We want to keep the columns that are + * still available in the new index pattern and remove the ones that are not. + * If the resulting array is empty, it provides a fallback to the default column. + * @param columns Array of column names + * @param indexPattern Index pattern object + * @param defaultColumns Array of default columns + */ +export function filterColumns( + columns: string[], + indexPattern: IndexPattern, + defaultColumns: string[] +) { + const fieldsName = indexPattern?.fields.getAll().map((fld) => fld.name) || []; + const filteredColumns = columns.filter((column) => fieldsName.includes(column)); + return filteredColumns.length > 0 ? filteredColumns : defaultColumns; +}