diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AppRouter/DomainRouter.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AppRouter/DomainRouter.tsx
index 2e0c56eb7aa..67c0c327fb0 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/AppRouter/DomainRouter.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/AppRouter/DomainRouter.tsx
@@ -46,7 +46,7 @@ const DomainRouter = () => {
index
element={
-
+
}
path="/"
@@ -54,7 +54,7 @@ const DomainRouter = () => {
-
+
}
path={ROUTES.DOMAIN_DETAILS.replace(ROUTES.DOMAIN, '')}
@@ -62,7 +62,7 @@ const DomainRouter = () => {
-
+
}
path={ROUTES.DOMAIN_DETAILS_WITH_TAB.replace(ROUTES.DOMAIN, '')}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataProduct/DataProductListPage.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataProduct/DataProductListPage.tsx
index 828307845f2..b95ab93c31b 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/DataProduct/DataProductListPage.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DataProduct/DataProductListPage.tsx
@@ -17,36 +17,51 @@ import { AxiosError } from 'axios';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ERROR_MESSAGE } from '../../constants/constants';
+import { SearchIndex } from '../../enums/search.enum';
import { CreateDataProduct } from '../../generated/api/domains/createDataProduct';
import { withPageLayout } from '../../hoc/withPageLayout';
import { addDataProducts } from '../../rest/dataProductAPI';
import { getIsErrorMatch } from '../../utils/CommonUtils';
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
import { useDelete } from '../common/atoms/actions/useDelete';
+import { useDataProductFilters } from '../common/atoms/domain/ui/useDataProductFilters';
import { useDomainCardTemplates } from '../common/atoms/domain/ui/useDomainCardTemplates';
import { useFormDrawerWithRef } from '../common/atoms/drawer';
-import { useFilterConfig } from '../common/atoms/filters/useFilterConfig';
-import { useFilterDropdowns } from '../common/atoms/filters/useFilterDropdowns';
+import { useQuickFilters } from '../common/atoms/filters/useQuickFilters';
import { useBreadcrumbs } from '../common/atoms/navigation/useBreadcrumbs';
import { usePageHeader } from '../common/atoms/navigation/usePageHeader';
import { useSearch } from '../common/atoms/navigation/useSearch';
import { useTitleAndCount } from '../common/atoms/navigation/useTitleAndCount';
import { useViewToggle } from '../common/atoms/navigation/useViewToggle';
import { usePaginationControls } from '../common/atoms/pagination/usePaginationControls';
-import { DATA_PRODUCT_FILTER_CONFIGS } from '../common/atoms/shared/utils/commonFilterConfigs';
import { useCardView } from '../common/atoms/table/useCardView';
import { useDataTable } from '../common/atoms/table/useDataTable';
import AddDomainForm from '../Domain/AddDomainForm/AddDomainForm.component';
import { DomainFormType } from '../Domain/DomainPage.interface';
import { useDataProductListingData } from './hooks/useDataProductListingData';
-const DataProductListPage = () => {
+const DataProductListPage = ({ pageTitle }: { pageTitle: string }) => {
const dataProductListing = useDataProductListingData();
const theme = useTheme();
const { t } = useTranslation();
const [form] = useForm();
const [isLoading, setIsLoading] = useState(false);
+ // Use data product-specific filters configuration
+ const dataProductFilters = useDataProductFilters({
+ enabledFilters: ['owner', 'expert', 'tags', 'glossary'],
+ });
+
+ const { quickFilters } = useQuickFilters({
+ filterFields: dataProductFilters.filterFields,
+ filterConfigs: dataProductFilters.filterConfigs,
+ queryConfig: dataProductFilters.queryConfig,
+ onFilterChange: dataProductListing.handleFilterChange,
+ aggregations: dataProductListing.aggregations || {},
+ searchIndex: SearchIndex.DATA_PRODUCT,
+ independent: true,
+ });
+
const { formDrawer, openDrawer, closeDrawer } = useFormDrawerWithRef({
title: t('label.add-entity', { entity: t('label.data-product') }),
anchor: 'right',
@@ -101,14 +116,6 @@ const DataProductListPage = () => {
loading: isLoading,
});
- const { dropdownConfigs } = useFilterConfig({
- filterConfigs: DATA_PRODUCT_FILTER_CONFIGS,
- filterOptions: dataProductListing.filterOptions || {},
- selectedFilters: dataProductListing.urlState.filters,
- onFilterChange: dataProductListing.handleFilterChange,
- onFilterSearch: dataProductListing.searchFilterOptions,
- });
-
// Composable hooks for each UI component
const { breadcrumbs } = useBreadcrumbs({
entityLabelKey: 'label.data-product',
@@ -135,10 +142,6 @@ const DataProductListPage = () => {
initialSearchQuery: dataProductListing.urlState.searchQuery,
});
- const { filterDropdowns } = useFilterDropdowns({
- filters: dropdownConfigs,
- });
-
const { view, viewToggle } = useViewToggle();
const { dataProductCardTemplate } = useDomainCardTemplates();
@@ -190,7 +193,7 @@ const DataProductListPage = () => {
}}>
{titleAndCount}
{search}
- {filterDropdowns}
+ {quickFilters}
{viewToggle}
{deleteIconButton}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Domain/DomainDetailPage/DomainDetailPage.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Domain/DomainDetailPage/DomainDetailPage.test.tsx
index 8ca20f63a43..1d1dfcf1a79 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Domain/DomainDetailPage/DomainDetailPage.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Domain/DomainDetailPage/DomainDetailPage.test.tsx
@@ -13,7 +13,7 @@
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
-import { MOCK_DOMAINS } from '../../../mocks/Domains.mock';
+import { DOMAINS_LIST } from '../../../mocks/Domains.mock';
import { getDomainByName } from '../../../rest/domainAPI';
import DomainDetailPage from './DomainDetailPage.component';
@@ -38,7 +38,7 @@ const mockGetDomainByName = getDomainByName as jest.MockedFunction<
describe('DomainDetailPage', () => {
beforeEach(() => {
- mockGetDomainByName.mockResolvedValue(MOCK_DOMAINS[0]);
+ mockGetDomainByName.mockResolvedValue(DOMAINS_LIST[0]);
});
it('should render domain detail page', async () => {
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Domain/SubDomainsTable/SubDomainsTable.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Domain/SubDomainsTable/SubDomainsTable.component.tsx
index 223db22fd88..5107151ee39 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Domain/SubDomainsTable/SubDomainsTable.component.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Domain/SubDomainsTable/SubDomainsTable.component.tsx
@@ -12,15 +12,15 @@
*/
import { Box, Paper, TableContainer, useTheme } from '@mui/material';
+import { SearchIndex } from '../../../enums/search.enum';
import { useDelete } from '../../common/atoms/actions/useDelete';
import { useDomainCardTemplates } from '../../common/atoms/domain/ui/useDomainCardTemplates';
-import { useFilterConfig } from '../../common/atoms/filters/useFilterConfig';
-import { useFilterDropdowns } from '../../common/atoms/filters/useFilterDropdowns';
+import { useDomainFilters } from '../../common/atoms/domain/ui/useDomainFilters';
+import { useQuickFilters } from '../../common/atoms/filters/useQuickFilters';
import { useSearch } from '../../common/atoms/navigation/useSearch';
import { useTitleAndCount } from '../../common/atoms/navigation/useTitleAndCount';
import { useViewToggle } from '../../common/atoms/navigation/useViewToggle';
import { usePaginationControls } from '../../common/atoms/pagination/usePaginationControls';
-import { SUBDOMAIN_FILTER_CONFIGS } from '../../common/atoms/shared/utils/commonFilterConfigs';
import { useCardView } from '../../common/atoms/table/useCardView';
import { useDataTable } from '../../common/atoms/table/useDataTable';
import { useSubdomainListingData } from './hooks/useSubdomainListingData';
@@ -36,12 +36,19 @@ const SubDomainsTable = ({
parentDomainFqn: domainFqn,
});
- const { dropdownConfigs } = useFilterConfig({
- filterConfigs: SUBDOMAIN_FILTER_CONFIGS,
- filterOptions: subdomainListing.filterOptions || {},
- selectedFilters: subdomainListing.urlState.filters,
+ // Use the same domain filters configuration
+ const domainFilters = useDomainFilters({
+ enabledFilters: ['owner', 'tags', 'glossary', 'domainType'],
+ });
+
+ const { quickFilters } = useQuickFilters({
+ filterFields: domainFilters.filterFields,
+ filterConfigs: domainFilters.filterConfigs,
+ queryConfig: domainFilters.queryConfig,
onFilterChange: subdomainListing.handleFilterChange,
- onFilterSearch: subdomainListing.searchFilterOptions,
+ aggregations: subdomainListing.aggregations || {},
+ searchIndex: SearchIndex.DOMAIN,
+ independent: true,
});
const { titleAndCount } = useTitleAndCount({
@@ -51,15 +58,11 @@ const SubDomainsTable = ({
});
const { search } = useSearch({
- searchPlaceholder: 'Search subdomains',
+ searchPlaceholderKey: 'label.search-subdomain',
onSearchChange: subdomainListing.handleSearchChange,
initialSearchQuery: subdomainListing.urlState.searchQuery,
});
- const { filterDropdowns } = useFilterDropdowns({
- filters: dropdownConfigs,
- });
-
const { view, viewToggle } = useViewToggle();
const { domainCardTemplate } = useDomainCardTemplates();
@@ -108,7 +111,7 @@ const SubDomainsTable = ({
}}>
{titleAndCount}
{search}
- {filterDropdowns}
+ {quickFilters}
{viewToggle}
{deleteIconButton}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DomainListing/DomainListPage.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DomainListing/DomainListPage.tsx
index 065c49e4668..f60a225504f 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/DomainListing/DomainListPage.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DomainListing/DomainListPage.tsx
@@ -17,22 +17,22 @@ import { AxiosError } from 'axios';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ERROR_MESSAGE } from '../../constants/constants';
+import { SearchIndex } from '../../enums/search.enum';
import { withPageLayout } from '../../hoc/withPageLayout';
import { addDomains } from '../../rest/domainAPI';
import { getIsErrorMatch } from '../../utils/CommonUtils';
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
import { useDelete } from '../common/atoms/actions/useDelete';
import { useDomainCardTemplates } from '../common/atoms/domain/ui/useDomainCardTemplates';
+import { useDomainFilters } from '../common/atoms/domain/ui/useDomainFilters';
import { useFormDrawerWithRef } from '../common/atoms/drawer';
-import { useFilterConfig } from '../common/atoms/filters/useFilterConfig';
-import { useFilterDropdowns } from '../common/atoms/filters/useFilterDropdowns';
+import { useQuickFilters } from '../common/atoms/filters/useQuickFilters';
import { useBreadcrumbs } from '../common/atoms/navigation/useBreadcrumbs';
import { usePageHeader } from '../common/atoms/navigation/usePageHeader';
import { useSearch } from '../common/atoms/navigation/useSearch';
import { useTitleAndCount } from '../common/atoms/navigation/useTitleAndCount';
import { useViewToggle } from '../common/atoms/navigation/useViewToggle';
import { usePaginationControls } from '../common/atoms/pagination/usePaginationControls';
-import { DOMAIN_FILTER_CONFIGS } from '../common/atoms/shared/utils/commonFilterConfigs';
import { useCardView } from '../common/atoms/table/useCardView';
import { useDataTable } from '../common/atoms/table/useDataTable';
import AddDomainForm from '../Domain/AddDomainForm/AddDomainForm.component';
@@ -46,6 +46,20 @@ const DomainListPage = () => {
const [form] = useForm();
const [isLoading, setIsLoading] = useState(false);
+ // Use the existing domain filters configuration
+ const domainFilters = useDomainFilters({
+ enabledFilters: ['owner', 'tags', 'glossary', 'domainType'],
+ });
+
+ const { quickFilters } = useQuickFilters({
+ filterFields: domainFilters.filterFields,
+ filterConfigs: domainFilters.filterConfigs,
+ queryConfig: domainFilters.queryConfig,
+ onFilterChange: domainListing.handleFilterChange,
+ aggregations: domainListing.aggregations || {},
+ searchIndex: SearchIndex.DOMAIN,
+ });
+
const { formDrawer, openDrawer, closeDrawer } = useFormDrawerWithRef({
title: t('label.add-entity', { entity: t('label.domain') }),
anchor: 'right',
@@ -99,14 +113,6 @@ const DomainListPage = () => {
loading: isLoading,
});
- const { dropdownConfigs } = useFilterConfig({
- filterConfigs: DOMAIN_FILTER_CONFIGS,
- filterOptions: domainListing.filterOptions || {},
- selectedFilters: domainListing.urlState.filters,
- onFilterChange: domainListing.handleFilterChange,
- onFilterSearch: domainListing.searchFilterOptions,
- });
-
// Composable hooks for each UI component
const { breadcrumbs } = useBreadcrumbs({
entityLabelKey: 'label.domain',
@@ -133,10 +139,6 @@ const DomainListPage = () => {
initialSearchQuery: domainListing.urlState.searchQuery,
});
- const { filterDropdowns } = useFilterDropdowns({
- filters: dropdownConfigs,
- });
-
const { view, viewToggle } = useViewToggle();
const { domainCardTemplate } = useDomainCardTemplates();
@@ -188,7 +190,7 @@ const DomainListPage = () => {
}}>
{titleAndCount}
{search}
- {filterDropdowns}
+ {quickFilters}
{viewToggle}
{deleteIconButton}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/compositions/useListingData.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/compositions/useListingData.tsx
index 33c027a7baf..aad86dc509c 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/compositions/useListingData.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/compositions/useListingData.tsx
@@ -13,8 +13,8 @@
import { useCallback, useEffect, useMemo } from 'react';
import { SearchIndex } from '../../../../enums/search.enum';
+import { getAggregations } from '../../../../utils/ExploreUtils';
import { useDataFetching } from '../data/useDataFetching';
-import { useFilterOptions } from '../data/useFilterOptions';
import { useSelectionState } from '../data/useSelectionState';
import { useUrlState } from '../data/useUrlState';
import { usePaginationState } from '../pagination/usePaginationState';
@@ -80,11 +80,6 @@ export const useListingData = (
const selectionState = useSelectionState(dataFetching.entities);
- const filterOptionsHook = useFilterOptions({
- searchIndex,
- filterFields,
- });
-
const actionHandlers = useActionHandlers({
basePath,
getEntityPath,
@@ -176,11 +171,12 @@ export const useListingData = (
clearSelection: selectionState.clearSelection,
urlState,
actionHandlers,
- filterOptions: filterOptionsHook.filterOptions,
+ filterOptions: {},
+ aggregations: getAggregations(dataFetching.aggregations || {}),
handleSearchChange,
handleFilterChange,
handlePageChange,
- searchFilterOptions: filterOptionsHook.searchFilterOptions,
+ searchFilterOptions: () => Promise.resolve([]),
refetch,
};
};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useAggregationFetcher.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useAggregationFetcher.tsx
deleted file mode 100644
index ce3a749437d..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useAggregationFetcher.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { useCallback } from 'react';
-import { SearchIndex } from '../../../../enums/search.enum';
-import { getAggregationOptions } from '../../../../utils/ExploreUtils';
-import { FilterField } from '../types';
-
-/**
- * Fetches aggregation data from API for filter dropdowns
- *
- * @description
- * Pure API fetching hook that calls the aggregation endpoint to get
- * filter option data. Handles both initial fetch and search-within-filter.
- * Does not manage state - only makes API calls.
- *
- * @example
- * ```typescript
- * const fetchAggregation = useAggregationFetcher();
- * const result = await fetchAggregation(SearchIndex.DOMAIN, field, searchTerm);
- * ```
- *
- * @stability Stable - No external dependencies, pure function
- * @complexity Low - Single API call responsibility
- */
-export const useAggregationFetcher = () => {
- const fetchAggregation = useCallback(
- async (searchIndex: SearchIndex, field: FilterField, searchTerm = '') => {
- return await getAggregationOptions(
- searchIndex,
- field.aggregationField,
- searchTerm,
- JSON.stringify({}),
- false
- );
- },
- [] // No dependencies - pure API call
- );
-
- return fetchAggregation;
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useAggregationProcessor.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useAggregationProcessor.tsx
deleted file mode 100644
index 6ac8b3b60a6..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useAggregationProcessor.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { useCallback } from 'react';
-
-/**
- * Processes raw aggregation API response into SearchDropdownOption format
- *
- * @description
- * This hook converts the raw response from Elasticsearch aggregation APIs
- * into a standardized format that can be used by SearchDropdown components.
- * Handles both custom processors and default bucket processing.
- *
- * @example
- * ```typescript
- * const processResult = useAggregationProcessor();
- * const options = processResult(apiResponse, customProcessor);
- * ```
- *
- * @stability Stable - Uses empty dependency array for maximum stability
- * @complexity Low - Single transformation responsibility
- */
-export const useAggregationProcessor = () => {
- const processAggregationResult = useCallback(
- (
- result: unknown,
- processor?: (result: unknown) => unknown[]
- ): unknown[] => {
- if ((result as any)?.status !== 'fulfilled') {
- return [];
- }
-
- if (processor) {
- return processor(result);
- }
-
- // Default processing for simple aggregations
- const buckets = Object.values(
- (result as any).value?.data?.aggregations || {}
- )[0] as unknown;
-
- if (!(buckets as any)?.buckets) {
- return [];
- }
-
- return (
- (buckets as any)?.buckets?.map((bucket: any) => ({
- key: bucket.key,
- label: bucket.key,
- count: bucket.doc_count,
- })) || []
- );
- },
- [] // Empty dependency array ensures maximum stability
- );
-
- return processAggregationResult;
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useDataFetching.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useDataFetching.tsx
index a122955099d..15d6fdfbecc 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useDataFetching.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useDataFetching.tsx
@@ -14,6 +14,7 @@
import { AxiosError } from 'axios';
import { useCallback, useState } from 'react';
import { SearchIndex } from '../../../../enums/search.enum';
+import { Aggregations } from '../../../../interface/search.interface';
import { searchData } from '../../../../rest/miscAPI';
import { showErrorToast } from '../../../../utils/ToastUtils';
@@ -30,6 +31,7 @@ export interface DataFetchingResult {
loading: boolean;
error: Error | null;
totalEntities: number;
+ aggregations: Aggregations | null;
refetch: () => void;
searchEntities: (
page: number,
@@ -45,6 +47,7 @@ export const useDataFetching = (
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [totalEntities, setTotalEntities] = useState(0);
+ const [aggregations, setAggregations] = useState(null);
const {
searchIndex,
@@ -112,15 +115,18 @@ export const useDataFetching = (
// Process response
const transformedEntities = transformData(response.data);
const total = response.data?.hits?.total?.value || 0;
+ const responseAggregations = response.data?.aggregations || null;
// Update state
setEntities(transformedEntities);
setTotalEntities(total);
+ setAggregations(responseAggregations);
setError(null);
} catch (err) {
setError(err instanceof Error ? err : new Error('Search failed'));
setEntities([]);
setTotalEntities(0);
+ setAggregations(null);
showErrorToast(err as AxiosError);
} finally {
setLoading(false);
@@ -139,6 +145,7 @@ export const useDataFetching = (
loading,
error,
totalEntities,
+ aggregations,
refetch,
searchEntities,
};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterLoadingState.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterLoadingState.tsx
deleted file mode 100644
index bf4ecae3b68..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterLoadingState.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { useCallback, useState } from 'react';
-
-/**
- * Manages loading state for filter operations
- *
- * @description
- * Simple loading state manager specifically for filter-related operations.
- * Provides start/stop loading functions and current loading state.
- *
- * @example
- * ```typescript
- * const { loading, startLoading, stopLoading } = useFilterLoadingState();
- *
- * // In async operation:
- * startLoading();
- * await fetchData();
- * stopLoading();
- * ```
- *
- * @stability Stable - No external dependencies
- * @complexity Very Low - Simple state management only
- */
-export const useFilterLoadingState = () => {
- const [loading, setLoading] = useState(false);
-
- const startLoading = useCallback(() => {
- setLoading(true);
- }, []);
-
- const stopLoading = useCallback(() => {
- setLoading(false);
- }, []);
-
- return {
- loading,
- startLoading,
- stopLoading,
- };
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptions.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptions.tsx
deleted file mode 100644
index 6aa9bb5a587..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptions.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { SearchIndex } from '../../../../enums/search.enum';
-import { FilterField } from '../types';
-import { useFilterOptionsComposition } from './useFilterOptionsComposition';
-
-interface UseFilterOptionsProps {
- searchIndex: SearchIndex;
- filterFields: FilterField[];
-}
-
-/**
- * Complete filter options system for dropdown filters
- *
- * @description
- * Provides complete filter options functionality by composing multiple
- * micro hooks. This is the main interface for filter options that
- * components should use.
- *
- * Internally composed of:
- * - useAggregationProcessor: Data transformation
- * - useAggregationFetcher: API calls
- * - useFilterLoadingState: Loading management
- * - useFilterOptionsState: State management
- * - useFilterOptionsComposition: Orchestration
- *
- * @param config.searchIndex - Elasticsearch index to fetch aggregations from
- * @param config.filterFields - Array of fields to create filter options for
- *
- * @example
- * ```typescript
- * const { filterOptions, loading, searchFilterOptions } = useFilterOptions({
- * searchIndex: SearchIndex.DOMAIN,
- * filterFields: [COMMON_FILTER_FIELDS.owners]
- * });
- * ```
- *
- * @stability Stable - Composes stable micro hooks
- * @complexity Low - Simple composition interface
- */
-export const useFilterOptions = ({
- searchIndex,
- filterFields,
-}: UseFilterOptionsProps) => {
- return useFilterOptionsComposition({
- searchIndex,
- filterFields,
- });
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptionsComposition.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptionsComposition.tsx
deleted file mode 100644
index 688a640abd6..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptionsComposition.tsx
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { useCallback, useEffect } from 'react';
-import { SearchIndex } from '../../../../enums/search.enum';
-import { FilterField } from '../types';
-import { useAggregationFetcher } from './useAggregationFetcher';
-import { useAggregationProcessor } from './useAggregationProcessor';
-import { useFilterLoadingState } from './useFilterLoadingState';
-import { useFilterOptionsState } from './useFilterOptionsState';
-
-interface UseFilterOptionsCompositionProps {
- searchIndex: SearchIndex;
- filterFields: FilterField[];
-}
-
-/**
- * Composes filter option micro hooks into complete filter options system
- *
- * @description
- * Combines multiple micro hooks to provide complete filter options functionality:
- * - State management (useFilterOptionsState)
- * - API fetching (useAggregationFetcher)
- * - Data processing (useAggregationProcessor)
- * - Loading management (useFilterLoadingState)
- *
- * Each micro hook has a single responsibility, making this composition
- * easy to understand, test, and debug.
- *
- * @param config.searchIndex - Elasticsearch index to fetch aggregations from
- * @param config.filterFields - Array of fields to create filter options for
- *
- * @example
- * ```typescript
- * const { filterOptions, loading, searchFilterOptions } = useFilterOptionsComposition({
- * searchIndex: SearchIndex.DOMAIN,
- * filterFields: [COMMON_FILTER_FIELDS.owners, COMMON_FILTER_FIELDS.tags]
- * });
- * ```
- *
- * @stability Stable - Composes stable micro hooks
- * @complexity Low - Simple composition pattern
- */
-export const useFilterOptionsComposition = ({
- searchIndex,
- filterFields,
-}: UseFilterOptionsCompositionProps) => {
- // Micro hooks - each with single responsibility
- const processResult = useAggregationProcessor();
- const fetchAggregation = useAggregationFetcher();
- const { loading, startLoading, stopLoading } = useFilterLoadingState();
- const { filterOptions, setFilterOptions, updateFilterField } =
- useFilterOptionsState();
-
- // Fetch all filter options (initial load)
- const fetchAllFilterOptions = useCallback(async () => {
- startLoading();
- try {
- const results = await Promise.allSettled(
- filterFields.map((field) => fetchAggregation(searchIndex, field))
- );
-
- const newFilterOptions = filterFields.reduce((acc, field, index) => {
- acc[field.key] = processResult(results[index], field.processor);
-
- return acc;
- }, {} as Record);
-
- setFilterOptions(newFilterOptions);
- } catch (error) {
- // Reset to empty options on error
- setFilterOptions({});
- } finally {
- stopLoading();
- }
- }, [
- searchIndex,
- filterFields,
- fetchAggregation,
- processResult,
- startLoading,
- stopLoading,
- setFilterOptions,
- ]);
-
- // Search within specific filter field
- const searchFilterOptions = useCallback(
- async (fieldKey: string, searchTerm: string) => {
- const field = filterFields.find((f) => f.key === fieldKey);
- if (!field) {
- return;
- }
-
- if (!searchTerm.trim()) {
- fetchAllFilterOptions();
-
- return;
- }
-
- startLoading();
- try {
- const result = await fetchAggregation(searchIndex, field, searchTerm);
- const processedOptions = processResult(
- { status: 'fulfilled', value: result },
- field.processor
- );
- updateFilterField(fieldKey, processedOptions);
- } catch (error) {
- // Keep existing options on search error
- } finally {
- stopLoading();
- }
- },
- [
- filterFields,
- searchIndex,
- fetchAggregation,
- processResult,
- updateFilterField,
- startLoading,
- stopLoading,
- fetchAllFilterOptions,
- ]
- );
-
- // Load filter options on mount
- useEffect(() => {
- fetchAllFilterOptions();
- }, [fetchAllFilterOptions]);
-
- return {
- filterOptions,
- loading,
- refetch: fetchAllFilterOptions,
- searchFilterOptions,
- };
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptionsState.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptionsState.tsx
deleted file mode 100644
index 21772cc5363..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/data/useFilterOptionsState.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { useCallback, useState } from 'react';
-import { FilterOptions } from '../types';
-
-/**
- * Manages filter options state (data storage only)
- *
- * @description
- * Simple state manager for filter dropdown options. Stores the options
- * object and provides functions to update specific filter fields.
- * Does not fetch data - only manages state.
- *
- * @example
- * ```typescript
- * const { filterOptions, setFilterOptions, updateFilterField } = useFilterOptionsState();
- *
- * // Set all options
- * setFilterOptions({ owners: [...], tags: [...] });
- *
- * // Update specific field
- * updateFilterField('owners', newOwnerOptions);
- * ```
- *
- * @stability Stable - No external dependencies
- * @complexity Very Low - Basic state management only
- */
-export const useFilterOptionsState = () => {
- const [filterOptions, setFilterOptions] = useState({});
-
- const updateFilterField = useCallback(
- (fieldKey: string, options: unknown[]) => {
- setFilterOptions((prev) => ({
- ...prev,
- [fieldKey]: options,
- }));
- },
- []
- );
-
- const clearFilterOptions = useCallback(() => {
- setFilterOptions({});
- }, []);
-
- return {
- filterOptions,
- setFilterOptions,
- updateFilterField,
- clearFilterOptions,
- };
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/domain/ui/useDataProductFilters.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/domain/ui/useDataProductFilters.tsx
new file mode 100644
index 00000000000..2cbe68554ef
--- /dev/null
+++ b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/domain/ui/useDataProductFilters.tsx
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2024 Collate.
+ * Licensed 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 { useMemo } from 'react';
+import { FilterConfig, FilterField } from '../../shared/types';
+import { COMMON_FILTER_FIELDS } from '../../shared/utils/commonFilterConfigs';
+
+interface UseDataProductFiltersConfig {
+ enabledFilters?: string[];
+ customFilterFields?: FilterField[];
+ customFilterConfigs?: FilterConfig[];
+}
+
+export const useDataProductFilters = (
+ config: UseDataProductFiltersConfig = {}
+) => {
+ const { enabledFilters = ['owner', 'expert', 'tags', 'glossary'] } = config;
+
+ const filterKeys = useMemo(() => enabledFilters, []);
+
+ const queryConfig = useMemo(
+ () => ({
+ owner: 'owners.displayName.keyword',
+ expert: 'experts.displayName.keyword',
+ tags: 'classificationTags',
+ glossary: 'glossaryTags',
+ }),
+ []
+ );
+
+ const filterFields = useMemo(
+ () => [
+ COMMON_FILTER_FIELDS.owners,
+ COMMON_FILTER_FIELDS.experts,
+ COMMON_FILTER_FIELDS.tags,
+ COMMON_FILTER_FIELDS.glossary,
+ ],
+ []
+ );
+
+ const filterConfigs = useMemo(
+ () => [
+ {
+ key: 'owners',
+ labelKey: 'label.owner',
+ searchKey: 'owner.displayName',
+ optionsKey: 'owners',
+ selectedKey: 'owner',
+ },
+ {
+ key: 'experts',
+ labelKey: 'label.expert-plural',
+ searchKey: 'expert.displayName',
+ optionsKey: 'experts',
+ selectedKey: 'expert',
+ },
+ {
+ key: 'tags',
+ labelKey: 'label.tag-plural',
+ searchKey: 'tags.tagFQN',
+ optionsKey: 'tags',
+ selectedKey: 'tags',
+ },
+ {
+ key: 'glossary',
+ labelKey: 'label.glossary-term-plural',
+ searchKey: 'glossaryTerms',
+ optionsKey: 'glossary',
+ selectedKey: 'glossary',
+ },
+ ],
+ []
+ );
+
+ return {
+ filterKeys,
+ queryConfig,
+ filterFields,
+ filterConfigs,
+ };
+};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/domain/ui/useDomainFilters.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/domain/ui/useDomainFilters.tsx
index 25e6b9bc5fd..da59cc0af7c 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/domain/ui/useDomainFilters.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/domain/ui/useDomainFilters.tsx
@@ -22,11 +22,8 @@ interface UseDomainFiltersConfig {
}
export const useDomainFilters = (config: UseDomainFiltersConfig = {}) => {
- const {
- enabledFilters = ['owner', 'tags', 'glossary'], // Temporarily disabled domainType due to API errors
- customFilterFields = [],
- customFilterConfigs = [],
- } = config;
+ const { enabledFilters = ['owner', 'tags', 'glossary', 'domainType'] } =
+ config;
const filterKeys = useMemo(() => enabledFilters, []);
@@ -35,7 +32,7 @@ export const useDomainFilters = (config: UseDomainFiltersConfig = {}) => {
owner: 'owners.displayName.keyword',
tags: 'classificationTags',
glossary: 'glossaryTags',
- domainType: 'domainType',
+ domainType: 'domainType.keyword',
}),
[]
);
@@ -45,7 +42,7 @@ export const useDomainFilters = (config: UseDomainFiltersConfig = {}) => {
COMMON_FILTER_FIELDS.owners,
COMMON_FILTER_FIELDS.tags,
COMMON_FILTER_FIELDS.glossary,
- // COMMON_FILTER_FIELDS.domainTypes, // Temporarily disabled
+ COMMON_FILTER_FIELDS.domainTypes, // Temporarily disabled
],
[]
);
@@ -73,7 +70,13 @@ export const useDomainFilters = (config: UseDomainFiltersConfig = {}) => {
optionsKey: 'glossary',
selectedKey: 'glossary',
},
- // domainType temporarily disabled
+ {
+ key: 'domainTypes',
+ labelKey: 'label.domain-type',
+ searchKey: 'domainType',
+ optionsKey: 'domainTypes',
+ selectedKey: 'domainType',
+ },
],
[]
);
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useEntityFiltersGeneric.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useEntityFiltersGeneric.tsx
deleted file mode 100644
index e16ad98761e..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useEntityFiltersGeneric.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { Box } from '@mui/material';
-import { useMemo } from 'react';
-import { useTranslation } from 'react-i18next';
-import SearchDropdown from '../../../SearchDropdown/SearchDropdown';
-import { SearchDropdownOption } from '../../../SearchDropdown/SearchDropdown.interface';
-
-interface FilterConfig {
- key: string;
- labelKey: string;
- searchKey: string;
- options: SearchDropdownOption[];
- selectedOptions: SearchDropdownOption[];
- onChange: (values: string[]) => void;
- onSearch: (searchTerm: string) => void;
-}
-
-interface EntityFiltersGenericConfig {
- filters: FilterConfig[];
-}
-
-export const useEntityFiltersGeneric = (config: EntityFiltersGenericConfig) => {
- const { t } = useTranslation();
-
- // Inline implementation copying exact EntityFiltersGeneric functionality
- const entityFiltersGeneric = useMemo(
- () => (
-
- {config.filters.map((filter) => (
- {
- filter.onChange(values.map((v) => v.key));
- }}
- onSearch={filter.onSearch}
- />
- ))}
-
- ),
- [config, t]
- );
-
- return {
- entityFiltersGeneric,
- hasActiveFilters: config.filters.some(
- (filter) => filter.selectedOptions.length > 0
- ),
- clearAllFilters: () =>
- config.filters.forEach((filter) => filter.onChange([])),
- };
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useFilterConfig.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useFilterConfig.tsx
deleted file mode 100644
index 01be2045627..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useFilterConfig.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { useMemo } from 'react';
-import { DropdownConfig, FilterConfig, FilterOptions } from '../types';
-
-interface UseFilterConfigProps {
- filterConfigs: FilterConfig[];
- filterOptions: FilterOptions;
- selectedFilters: Record;
- onFilterChange: (key: string, values: string[]) => void;
- onFilterSearch: (key: string, term: string) => void;
-}
-
-export const useFilterConfig = (props: UseFilterConfigProps) => {
- const {
- filterConfigs,
- filterOptions,
- selectedFilters,
- onFilterChange,
- onFilterSearch,
- } = props;
-
- const dropdownConfigs: DropdownConfig[] = useMemo(() => {
- return filterConfigs.map((config) => ({
- key: config.key,
- labelKey: config.labelKey,
- searchKey: config.searchKey,
- options: filterOptions[config.optionsKey] || [],
- selectedOptions: selectedFilters[config.selectedKey] || [],
- onChange: (values: string[]) => onFilterChange(config.key, values),
- onSearch: (term: string) => onFilterSearch(config.optionsKey, term),
- }));
- }, [
- filterConfigs,
- filterOptions,
- selectedFilters,
- onFilterChange,
- onFilterSearch,
- ]);
-
- return {
- dropdownConfigs,
- };
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useFilterDropdowns.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useFilterDropdowns.tsx
deleted file mode 100644
index 6bff97e1c1e..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useFilterDropdowns.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2024 Collate.
- * Licensed 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 { useMemo } from 'react';
-import { useTranslation } from 'react-i18next';
-import { SearchDropdownOption } from '../../../SearchDropdown/SearchDropdown.interface';
-import { useEntityFiltersGeneric } from './useEntityFiltersGeneric';
-
-interface FilterDropdownsConfig {
- filters: Array<{
- key: string;
- labelKey: string;
- searchKey: string;
- options: any[];
- selectedOptions: any[];
- onChange: (values: string[]) => void;
- onSearch: (term: string) => void;
- }>;
-}
-
-export const useFilterDropdowns = (config: FilterDropdownsConfig) => {
- const { t } = useTranslation();
-
- // Convert our filter format to the format expected by useEntityFiltersGeneric
- const convertedFilters = useMemo(() => {
- return config.filters.map((filter) => ({
- key: filter.key,
- labelKey: filter.labelKey,
- searchKey: filter.searchKey,
- options: filter.options.map(
- (option): SearchDropdownOption => ({
- key: option.key || option.label || option,
- label: option.label || option.key || option,
- count: option.count || 0,
- })
- ),
- selectedOptions: filter.selectedOptions.map(
- (option): SearchDropdownOption => ({
- key: typeof option === 'string' ? option : option.key || option.label,
- label:
- typeof option === 'string' ? option : option.label || option.key,
- count: typeof option === 'object' ? option.count || 0 : 0,
- })
- ),
- onChange: filter.onChange,
- onSearch: filter.onSearch,
- }));
- }, [config.filters]);
-
- const { entityFiltersGeneric, hasActiveFilters, clearAllFilters } =
- useEntityFiltersGeneric({
- filters: convertedFilters,
- });
-
- return {
- filterDropdowns: entityFiltersGeneric,
- clearAllFilters,
- hasActiveFilters,
- filterCount: config.filters.length,
- };
-};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useQuickFilters.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useQuickFilters.tsx
new file mode 100644
index 00000000000..0401f8e1c68
--- /dev/null
+++ b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/filters/useQuickFilters.tsx
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2024 Collate.
+ * Licensed 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 { useCallback, useMemo, useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { SearchIndex } from '../../../../enums/search.enum';
+import { Aggregations } from '../../../../interface/search.interface';
+import { ExploreQuickFilterField } from '../../../Explore/ExplorePage.interface';
+import ExploreQuickFilters from '../../../Explore/ExploreQuickFilters';
+import { FilterConfig, FilterField } from '../shared/types';
+
+interface QuickFiltersConfig {
+ filterFields: FilterField[];
+ filterConfigs: FilterConfig[];
+ queryConfig: Record;
+ onFilterChange: (filterKey: string, values: string[]) => void;
+ aggregations: Aggregations;
+ searchIndex: SearchIndex;
+ independent?: boolean;
+}
+
+export const useQuickFilters = (config: QuickFiltersConfig) => {
+ const { t } = useTranslation();
+
+ const initialFilters = useMemo(
+ () =>
+ config.filterFields.map((field) => {
+ const filterConfig = config.filterConfigs.find(
+ (fc) => fc.key === field.key
+ );
+
+ return {
+ key: field.aggregationField,
+ label: filterConfig ? t(filterConfig.labelKey) : field.key,
+ value: [],
+ };
+ }),
+ [config.filterFields, config.filterConfigs, t]
+ );
+
+ const [selectedQuickFilters, setSelectedQuickFilters] =
+ useState(initialFilters);
+
+ const getFilterKeyFromField = useCallback(
+ (fieldKey: string): string => {
+ // Reverse lookup from aggregationField to filter key
+ const entry = Object.entries(config.queryConfig).find(
+ ([, value]) => value === fieldKey
+ );
+
+ return entry ? entry[0] : fieldKey;
+ },
+ [config.queryConfig]
+ );
+
+ const handleQuickFiltersValueSelect = useCallback(
+ (field: ExploreQuickFilterField) => {
+ setSelectedQuickFilters((prev) => {
+ const data = prev.map((prevField) => {
+ if (prevField.key === field.key) {
+ return field;
+ }
+
+ return prevField;
+ });
+
+ const filterKey = getFilterKeyFromField(field.key);
+ config.onFilterChange(filterKey, field.value?.map((v) => v.key) || []);
+
+ return data;
+ });
+ },
+ [config.onFilterChange, getFilterKeyFromField]
+ );
+
+ const quickFilters = useMemo(
+ () => (
+
+ ),
+ [
+ config.independent,
+ config.aggregations,
+ config.searchIndex,
+ selectedQuickFilters,
+ handleQuickFiltersValueSelect,
+ ]
+ );
+
+ return {
+ quickFilters,
+ selectedQuickFilters,
+ handleQuickFiltersValueSelect,
+ };
+};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/shared/types/index.ts b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/shared/types/index.ts
index d042581ccc9..df98286ccad 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/shared/types/index.ts
+++ b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/shared/types/index.ts
@@ -12,6 +12,7 @@
*/
import { ReactNode } from 'react';
+import { Aggregations } from '../../../../../interface/search.interface';
export interface UrlStateConfig {
searchKey?: string;
@@ -123,6 +124,7 @@ export interface ListingData {
urlState: UrlState;
actionHandlers: ActionHandlers;
filterOptions?: FilterOptions;
+ aggregations?: Aggregations | null;
handleSearchChange: (query: string) => void;
handleFilterChange: (key: string, values: string[]) => void;
handlePageChange: (page: number) => void;
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/shared/utils/commonFilterConfigs.ts b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/shared/utils/commonFilterConfigs.ts
index 49da1e7318a..d032dd1ac32 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/shared/utils/commonFilterConfigs.ts
+++ b/openmetadata-ui/src/main/resources/ui/src/components/common/atoms/shared/utils/commonFilterConfigs.ts
@@ -11,19 +11,16 @@
* limitations under the License.
*/
-import { FilterConfig, FilterField } from '../types';
-import { processOwnerOptions } from './entityFilterProcessors';
+import { FilterField } from '../types';
export const COMMON_FILTER_FIELDS: Record = {
owners: {
key: 'owners',
aggregationField: 'owners.displayName.keyword',
- processor: processOwnerOptions,
},
experts: {
key: 'experts',
aggregationField: 'experts.displayName.keyword',
- processor: processOwnerOptions,
},
tags: {
key: 'tags',
@@ -35,99 +32,6 @@ export const COMMON_FILTER_FIELDS: Record = {
},
domainTypes: {
key: 'domainTypes',
- aggregationField: 'domainType',
+ aggregationField: 'domainType.keyword',
},
};
-
-export const DOMAIN_FILTER_CONFIGS: FilterConfig[] = [
- {
- key: 'owner',
- labelKey: 'label.owner',
- searchKey: 'owner.displayName',
- optionsKey: 'owners',
- selectedKey: 'owner',
- },
- {
- key: 'tags',
- labelKey: 'label.tag-plural',
- searchKey: 'tags.tagFQN',
- optionsKey: 'tags',
- selectedKey: 'tags',
- },
- {
- key: 'glossary',
- labelKey: 'label.glossary-term-plural',
- searchKey: 'glossaryTerms',
- optionsKey: 'glossary',
- selectedKey: 'glossary',
- },
- {
- key: 'domainType',
- labelKey: 'label.domain-type',
- searchKey: 'domainType',
- optionsKey: 'domainTypes',
- selectedKey: 'domainType',
- },
-];
-
-export const DATA_PRODUCT_FILTER_CONFIGS: FilterConfig[] = [
- {
- key: 'owner',
- labelKey: 'label.owner',
- searchKey: 'owner.displayName',
- optionsKey: 'owners',
- selectedKey: 'owner',
- },
- {
- key: 'expert',
- labelKey: 'label.expert',
- searchKey: 'expert.displayName',
- optionsKey: 'experts',
- selectedKey: 'expert',
- },
- {
- key: 'tags',
- labelKey: 'label.tag-plural',
- searchKey: 'tags.tagFQN',
- optionsKey: 'tags',
- selectedKey: 'tags',
- },
- {
- key: 'glossary',
- labelKey: 'label.glossary-term-plural',
- searchKey: 'glossaryTerms',
- optionsKey: 'glossary',
- selectedKey: 'glossary',
- },
-];
-
-export const SUBDOMAIN_FILTER_CONFIGS: FilterConfig[] = [
- {
- key: 'owner',
- labelKey: 'label.owner',
- searchKey: 'owner.displayName',
- optionsKey: 'owners',
- selectedKey: 'owner',
- },
- {
- key: 'tags',
- labelKey: 'label.tag-plural',
- searchKey: 'tags.tagFQN',
- optionsKey: 'tags',
- selectedKey: 'tags',
- },
- {
- key: 'glossary',
- labelKey: 'label.glossary-term-plural',
- searchKey: 'glossaryTerms',
- optionsKey: 'glossary',
- selectedKey: 'glossary',
- },
- {
- key: 'domainType',
- labelKey: 'label.domain-type',
- searchKey: 'domainType',
- optionsKey: 'domainTypes',
- selectedKey: 'domainType',
- },
-];
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json
index 536f5a4bcdf..dbefe649af9 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Senden des Dateninsight-Berichts fehlgeschlagen.",
"data-insight-report-send-success-message": "Dateninsight-Bericht erfolgreich gesendet.",
"data-insight-subtitle": "Erhalten Sie einen einzigen Überblick über die Gesundheit aller Ihrer Datenvermögenswerte im Laufe der Zeit.",
- "data-products-no-data-message": "Es sieht so aus, als hätten Sie noch keine Datenprodukte hinzugefügt, erstellen Sie eines!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Es sieht so aus, als hätten Sie noch keine Datenprodukte hinzugefügt, erstellen Sie eines!",
"data-quality-test-contract-title": "Datenqualitätstests und -überprüfungen",
"database-service-name-message": "Fügen Sie die Namen der Datenbankdienste hinzu, um die Lineage zu erstellen.",
"dbt-catalog-file-extract-path": " Pfad zur dbt-Katalogdatei, um dbt-Modelle mit ihren Spaltenschemata zu extrahieren.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json
index 6f06c597b1e..b105f57e39b 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Error al enviar el informe de información de datos.",
"data-insight-report-send-success-message": "Informe de Información de Datos enviado correctamente.",
"data-insight-subtitle": "Obtenga una vista global de la salud de todos sus activos de datos a lo largo del tiempo.",
- "data-products-no-data-message": "Parece que no has agregado ningún producto de datos, ¡crea uno!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Parece que no has agregado ningún producto de datos, ¡crea uno!",
"data-quality-test-contract-title": "Pruebas de calidad de datos y aserciones",
"database-service-name-message": "Agregue los nombres de servicio de la base de datos para crear la dependencia del linaje.",
"dbt-catalog-file-extract-path": "Ruta del archivo de catálogo de dbt para extraer modelos de dbt con sus esquemas de columnas.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json
index b7f6c042056..ecc1cce9bb2 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Rapport de l'Aperçu des Données envoyé avec échec.",
"data-insight-report-send-success-message": "Rapport de l'Aperçu des Données envoyé avec succès.",
"data-insight-subtitle": "Obtenir une vue à 360 de la santé de vos actifs de données au fil du temps.",
- "data-products-no-data-message": "Il semble que vous n'ayez ajouté aucun produit de données, créez-en un !",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Il semble que vous n'ayez ajouté aucun produit de données, créez-en un !",
"data-quality-test-contract-title": "Tests et assertions de qualité des données",
"database-service-name-message": "Ajouter les noms de service de base de données pour créer la traçabilité.",
"dbt-catalog-file-extract-path": "fichier catalog.yml de dbt pour extraire les modèles dbt avec leurs schémas de colonnes.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json
index 145dcb8198b..97045230fe3 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Fallou o envío do informe de insights de datos.",
"data-insight-report-send-success-message": "Informe de insights de datos enviado correctamente.",
"data-insight-subtitle": "Obtén unha vista única da saúde de todos os teus activos de datos ao longo do tempo.",
- "data-products-no-data-message": "Parece que non engadiches ningún produto de datos, crea un!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Parece que non engadiches ningún produto de datos, crea un!",
"data-quality-test-contract-title": "Probas de calidade de datos e asercións",
"database-service-name-message": "Engade os nomes dos servizos da base de datos para crear liñaxe.",
"dbt-catalog-file-extract-path": "Ficheiro de catálogo dbt para extraer modelos dbt coas súas esquemas de columnas.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json
index 0d96a8f82d5..37e7b30e383 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "נכשל בשליחת דוח תובנות נתונים.",
"data-insight-report-send-success-message": "דוח תובנות נתונים נשלח בהצלחה.",
"data-insight-subtitle": "קבל תצוגה מרוכזת של הבריאות של כל הנכסים שלך מעל לאורך זמן.",
- "data-products-no-data-message": "נראה שלא הוספת מוצרי נתונים, צור אחד!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "נראה שלא הוספת מוצרי נתונים, צור אחד!",
"data-quality-test-contract-title": "בדיקות איכות נתונים ואישורים",
"database-service-name-message": "הוסף את שמות שירותי מסדי הנתונים ליצירת הקשריות.",
"dbt-catalog-file-extract-path": " נתיב קובץ קטלוג dbt לחשיפת מודלי dbt עם סכמות עמודותיהם.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json
index 833f8a7cf58..c1be5242ab5 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "データインサイトレポートの送信に失敗しました。",
"data-insight-report-send-success-message": "データインサイトレポートが正常に送信されました。",
"data-insight-subtitle": "すべてのデータアセットの健全性を一目で把握しましょう。",
- "data-products-no-data-message": "データプロダクトを追加していないようです、作成してください!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "データプロダクトを追加していないようです、作成してください!",
"data-quality-test-contract-title": "Data quality tests and assertions",
"database-service-name-message": "データベースサービス名を追加してリネージを作成します。",
"dbt-catalog-file-extract-path": "dbt カタログファイルのパス(モデルとカラムスキーマを抽出)",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json
index 9f9d8773fe1..5f8ef51c6e1 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "데이터 인사이트 보고서 전송에 실패했습니다.",
"data-insight-report-send-success-message": "데이터 인사이트 보고서가 성공적으로 전송되었습니다.",
"data-insight-subtitle": "시간에 따른 모든 데이터 자산의 건강 상태를 단일 창에서 볼 수 있습니다.",
- "data-products-no-data-message": "데이터 제품을 추가하지 않은 것 같습니다, 하나 만들어보세요!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "데이터 제품을 추가하지 않은 것 같습니다, 하나 만들어보세요!",
"data-quality-test-contract-title": "데이터 품질 테스트 및 검증",
"database-service-name-message": "계보를 생성하려면 데이터베이스 서비스 이름을 추가하세요.",
"dbt-catalog-file-extract-path": "열 스키마와 함께 dbt 모델을 추출하기 위한 dbt 카탈로그 파일입니다.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json
index 246c43a99fa..68c3cfd047b 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "डेटा अंतर्दृष्टी अहवाल पाठविण्यात अयशस्वी.",
"data-insight-report-send-success-message": "डेटा अंतर्दृष्टी अहवाल यशस्वीरित्या पाठवला.",
"data-insight-subtitle": "काळानुसार सर्व डेटा ॲसेटंच्या आरोग्याचे एकल दृश्य मिळवा.",
- "data-products-no-data-message": "असे दिसते की तुम्ही कोणतेही डेटा उत्पादने जोडली नाहीत, एक तयार करा!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "असे दिसते की तुम्ही कोणतेही डेटा उत्पादने जोडली नाहीत, एक तयार करा!",
"data-quality-test-contract-title": "डेटा गुणवत्ता चाचण्या आणि पुष्टीकरणे",
"database-service-name-message": "वंश तयार करण्यासाठी डेटाबेस सेवा नावे जोडा.",
"dbt-catalog-file-extract-path": "dbt कॅटलॉग फाइल dbt मॉडेल्स त्यांच्या स्तंभ योजना सह काढण्यासाठी.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json
index c50a8661501..23bb505c4aa 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Kan het rapport voor inzicht data-assets niet verzenden.",
"data-insight-report-send-success-message": "Rapport voor inzicht data-assets succesvol verzonden.",
"data-insight-subtitle": "Bekijk in één overzicht de statushistorie van al uw data-assets.",
- "data-products-no-data-message": "Het lijkt erop dat je geen dataproducten hebt toegevoegd, maak er een!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Het lijkt erop dat je geen dataproducten hebt toegevoegd, maak er een!",
"data-quality-test-contract-title": "Datakwaliteitstests en -bevestigingen",
"database-service-name-message": "Voeg de namen van databaseservices toe om herkomst vast te leggen.",
"dbt-catalog-file-extract-path": "Pad naar dbt-catalogusbestand om dbt-modellen met hun kolomschema's te extraheren.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json
index 2785ffbba06..b53f4ed1c47 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "ارسال گزارش بینش داده شکست خورد.",
"data-insight-report-send-success-message": "گزارش بینش داده با موفقیت ارسال شد.",
"data-insight-subtitle": "نمایی یکپارچه از سلامت تمام داراییهای دادهای شما در طول زمان.",
- "data-products-no-data-message": "به نظر میرسد هیچ محصول دادهای اضافه نکردهاید، یکی بسازید!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "به نظر میرسد هیچ محصول دادهای اضافه نکردهاید، یکی بسازید!",
"data-quality-test-contract-title": "تستهای کیفیت داده و تأییدها",
"database-service-name-message": "نامهای سرویس پایگاه داده را اضافه کنید تا خطمش را ایجاد کنید.",
"dbt-catalog-file-extract-path": "فایل کاتالوگ dbt برای استخراج مدلهای dbt با اسکیماهای ستون آنها.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json
index 4012767bfde..36a7886051b 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Falha ao enviar relatório de insight de dados.",
"data-insight-report-send-success-message": "Relatório de Insight de Dados enviado com sucesso.",
"data-insight-subtitle": "Obtenha uma visão única da saúde de todos os seus ativos de dados ao longo do tempo.",
- "data-products-no-data-message": "Parece que você não adicionou nenhum produto de dados, crie um!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Parece que você não adicionou nenhum produto de dados, crie um!",
"data-quality-test-contract-title": "Testes de qualidade de dados e afirmações",
"database-service-name-message": "Adicione os nomes dos serviços de banco de dados para criar linhagem.",
"dbt-catalog-file-extract-path": "Arquivo de catálogo dbt para extrair modelos dbt com seus esquemas de coluna.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json
index fc814858d48..3238f713418 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Falha ao enviar relatório de insight de dados.",
"data-insight-report-send-success-message": "Relatório de Insight de Dados enviado com sucesso.",
"data-insight-subtitle": "Obtenha uma visão única da saúde de todos os seus ativos de dados ao longo do tempo.",
- "data-products-no-data-message": "Parece que não adicionou nenhum produto de dados, crie um!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Parece que não adicionou nenhum produto de dados, crie um!",
"data-quality-test-contract-title": "Testes de qualidade de dados e afirmações",
"database-service-name-message": "Adicione os nomes dos serviços de banco de dados para criar linhagem.",
"dbt-catalog-file-extract-path": "Arquivo de catálogo dbt para extrair modelos dbt com seus esquemas de coluna.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json
index 11d03113495..320577a4522 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Не удалось отправить отчет об анализе данных",
"data-insight-report-send-success-message": "Отчет о анализе данных успешно отправлен.",
"data-insight-subtitle": "Получите единое представление о состоянии всех ваших активов данных с течением времени.",
- "data-products-no-data-message": "Похоже, вы не добавили никаких продуктов данных, создайте один!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Похоже, вы не добавили никаких продуктов данных, создайте один!",
"data-quality-test-contract-title": "Тесты качества данных и утверждения",
"database-service-name-message": "Добавьте имена сервиса базы данных, чтобы создать lineage.",
"dbt-catalog-file-extract-path": "dbt для извлечения моделей dbt со схемами их столбцов.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json
index 211b7e9ac27..5b6556885f6 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "ส่งรายงานข้อมูลเชิงลึกล้มเหลว",
"data-insight-report-send-success-message": "ส่งรายงานข้อมูลเชิงลึกสำเร็จ",
"data-insight-subtitle": "ดูภาพรวมของสุขภาพสินทรัพย์ข้อมูลทั้งหมดของคุณตลอดเวลา",
- "data-products-no-data-message": "ดูเหมือนว่าคุณยังไม่ได้เพิ่มผลิตภัณฑ์ข้อมูลใด ๆ สร้างหนึ่งรายการ!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "ดูเหมือนว่าคุณยังไม่ได้เพิ่มผลิตภัณฑ์ข้อมูลใด ๆ สร้างหนึ่งรายการ!",
"data-quality-test-contract-title": "Data quality tests and assertions",
"database-service-name-message": "เพิ่มชื่อบริการฐานข้อมูลเพื่อสร้างลำดับชั้น",
"dbt-catalog-file-extract-path": "ไฟล์ Catalog ของ dbt สำหรับดึงโมเดล dbt พร้อมกับสคีมาคอลัมน์ของพวกเขา",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/tr-tr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/tr-tr.json
index 6157225084a..8c0a6fba134 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/tr-tr.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/tr-tr.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "Veri analizi raporu gönderilemedi.",
"data-insight-report-send-success-message": "Veri Analizi Raporu başarıyla gönderildi.",
"data-insight-subtitle": "Tüm veri varlıklarınızın zaman içindeki sağlığının tek bir görünümünü elde edin.",
- "data-products-no-data-message": "Henüz bir veri ürünü eklememiş gibi görünüyor, bir tane oluşturun!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "Henüz bir veri ürünü eklememiş gibi görünüyor, bir tane oluşturun!",
"data-quality-test-contract-title": "Veri kalitesi testleri ve onaylar",
"database-service-name-message": "Veri soyu oluşturmak için veritabanı servis adlarını ekleyin.",
"dbt-catalog-file-extract-path": " dbt modellerini sütun şemalarıyla birlikte çıkarmak için dbt katalog dosyası.",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json
index 81a400dac05..d59cf05b675 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "数据洞察报告发送失败。",
"data-insight-report-send-success-message": "数据洞察报告发送成功。",
"data-insight-subtitle": "查看所有数据资产的健康状况",
- "data-products-no-data-message": "看起来您还没有添加任何数据产品,创建一个!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "看起来您还没有添加任何数据产品,创建一个!",
"data-quality-test-contract-title": "数据质量测试和断言",
"database-service-name-message": "添加数据库服务名称以创建血缘关系图",
"dbt-catalog-file-extract-path": "dbt 目录文件, 用于提取带有 Column Schema (列模式) 的 dbt 模型",
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-tw.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-tw.json
index a81127eedcb..312c3a4625f 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-tw.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-tw.json
@@ -1990,8 +1990,8 @@
"data-insight-report-send-failed-message": "傳送資料洞察報告失敗。",
"data-insight-report-send-success-message": "資料洞察報告傳送成功。",
"data-insight-subtitle": "在一個單一窗格中檢視您所有資料資產隨時間變化的健康狀況。",
- "data-products-no-data-message": "看起來您還沒有新增任何資料產品,建立一個!",
"data-product-description": "Manage and organize your data products for better data governance.",
+ "data-products-no-data-message": "看起來您還沒有新增任何資料產品,建立一個!",
"data-quality-test-contract-title": "資料品質測試與斷言",
"database-service-name-message": "新增資料庫服務名稱以建立血緣。",
"dbt-catalog-file-extract-path": "dbt 目錄檔案,用於擷取 dbt 模型及其欄位結構。",