diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreQuickFilters.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreQuickFilters.spec.ts index 3c941f8d775..e166c74b501 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreQuickFilters.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreQuickFilters.spec.ts @@ -10,12 +10,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import test from '@playwright/test'; +import test, { expect } from '@playwright/test'; import { SidebarItem } from '../../constant/sidebar'; import { Domain } from '../../support/domain/Domain'; import { TableClass } from '../../support/entity/TableClass'; import { assignDomain, + clickOutside, createNewPage, redirectToHomePage, } from '../../utils/common'; @@ -91,7 +92,7 @@ test('should search for empty or null filters', async ({ page }) => { } }); -test('should search for multiple values alongwith null filters', async ({ +test('should search for multiple values along with null filters', async ({ page, }) => { const items = [ @@ -111,3 +112,37 @@ test('should search for multiple values alongwith null filters', async ({ await selectNullOption(page, filter); } }); + +test('should persist quick filter on global search', async ({ page }) => { + const items = [{ label: 'Owners', key: 'owners.displayName.keyword' }]; + + for (const filter of items) { + await selectNullOption(page, filter, false); + } + + const waitForSearchResponse = page.waitForResponse( + '/api/v1/search/query?q=*index=dataAsset*' + ); + + await page + .getByTestId('searchBox') + .fill(table.entityResponseData.fullyQualifiedName); + await waitForSearchResponse; + + await clickOutside(page); + + // expect the quick filter to be persisted + await expect( + page.getByRole('button', { name: 'Owners : No Owners' }) + ).toBeVisible(); + + await page.getByTestId('searchBox').click(); + await page.keyboard.down('Enter'); + + await page.waitForLoadState('networkidle'); + + // expect the quick filter to be persisted + await expect( + page.getByRole('button', { name: 'Owners : No Owners' }) + ).toBeVisible(); +}); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Navbar.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Navbar.spec.ts index a67465bb3ce..9512e14fff9 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Navbar.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Navbar.spec.ts @@ -35,7 +35,7 @@ for (const searchItem of navbarSearchItems) { ); const searchRes = page.waitForResponse( - `/api/v1/search/query?q=*&index=${searchIndex}` + `/api/v1/search/query?q=*&index=${searchIndex}**` ); await page.getByTestId('searchBox').fill('dim'); await searchRes; diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/explore.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/explore.ts index f3bb5b71ac0..fbe68ab04da 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/explore.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/explore.ts @@ -45,7 +45,8 @@ export const searchAndClickOnOption = async ( export const selectNullOption = async ( page: Page, - filter: { key: string; label: string; value?: string } + filter: { key: string; label: string; value?: string }, + clearFilter = true ) => { const queryFilter = JSON.stringify({ query: { @@ -101,7 +102,9 @@ export const selectNullOption = async ( expect(isQueryFilterPresent).toBeTruthy(); - await page.click(`[data-testid="clear-filters"]`); + if (clearFilter) { + await page.click(`[data-testid="clear-filters"]`); + } }; export const checkCheckboxStatus = async ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Appbar.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Appbar.tsx index 910a8530252..fae6f2ad736 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Appbar.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Appbar.tsx @@ -76,7 +76,7 @@ const Appbar: React.FC = (): JSX.Element => { getExplorePath({ tab: defaultTab, search: value, - isPersistFilters: false, + isPersistFilters: true, extraParameters: { sort: '_score', }, diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Suggestions.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Suggestions.tsx index d3d15043eb5..81ac9ef0cf1 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Suggestions.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AppBar/Suggestions.tsx @@ -13,8 +13,15 @@ import { Typography } from 'antd'; import { AxiosError } from 'axios'; -import { isEmpty } from 'lodash'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { isEmpty, isString } from 'lodash'; +import Qs from 'qs'; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import { useTranslation } from 'react-i18next'; import { PAGE_SIZE_BASE } from '../../constants/constants'; import { @@ -43,7 +50,7 @@ import { DashboardDataModelSearchSource, StoredProcedureSearchSource, } from '../../interface/search.interface'; -import { searchData } from '../../rest/miscAPI'; +import { searchQuery } from '../../rest/searchAPI'; import { Transi18next } from '../../utils/CommonUtils'; import searchClassBase from '../../utils/SearchClassBase'; import { @@ -171,6 +178,18 @@ const Suggestions = ({ ); }; + const quickFilter = useMemo(() => { + const parsedSearch = Qs.parse( + location.search.startsWith('?') + ? location.search.substring(1) + : location.search + ); + + return !isString(parsedSearch.quickFilter) + ? {} + : JSON.parse(parsedSearch.quickFilter); + }, [location.search]); + const getSuggestionsForIndex = ( suggestions: SearchSuggestions, searchIndex: SearchIndex @@ -264,23 +283,16 @@ const Suggestions = ({ const fetchSearchData = useCallback(async () => { try { setIsLoading(true); - const res = await searchData( - searchText, - 1, - PAGE_SIZE_BASE, - '', - '', - '', - searchCriteria ?? SearchIndex.DATA_ASSET, - false, - false, - false - ); - if (res.data) { - setOptions(res.data.hits.hits as unknown as Option[]); - updateSuggestions(res.data.hits.hits as unknown as Option[]); - } + const res = await searchQuery({ + query: searchText, + searchIndex: searchCriteria ?? SearchIndex.DATA_ASSET, + queryFilter: quickFilter, + pageSize: PAGE_SIZE_BASE, + }); + + setOptions(res.hits.hits as unknown as Option[]); + updateSuggestions(res.hits.hits as unknown as Option[]); } catch (err) { showErrorToast( err as AxiosError,