diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/ExplorePage.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Explore/ExplorePage.interface.ts index ee51576c34c..cfcce6e91b6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/ExplorePage.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/ExplorePage.interface.ts @@ -14,6 +14,8 @@ import { ItemType } from 'antd/lib/menu/hooks/useItems'; import { SORT_ORDER } from '../../enums/common.enum'; import { SearchIndex } from '../../enums/search.enum'; +import { Kpi } from '../../generated/dataInsight/kpi/kpi'; +import { AppMarketPlaceDefinition } from '../../generated/entity/applications/marketplace/appMarketPlaceDefinition'; import { Tag } from '../../generated/entity/classification/tag'; import { APICollection } from '../../generated/entity/data/apiCollection'; import { APIEndpoint } from '../../generated/entity/data/apiEndpoint'; @@ -26,6 +28,7 @@ import { Glossary } from '../../generated/entity/data/glossary'; import { Metric } from '../../generated/entity/data/metric'; import { Mlmodel } from '../../generated/entity/data/mlmodel'; import { Pipeline } from '../../generated/entity/data/pipeline'; +import { Query } from '../../generated/entity/data/query'; import { SearchIndex as SearchIndexEntity } from '../../generated/entity/data/searchIndex'; import { StoredProcedure } from '../../generated/entity/data/storedProcedure'; import { Table } from '../../generated/entity/data/table'; @@ -33,12 +36,15 @@ import { Topic } from '../../generated/entity/data/topic'; import { APIService } from '../../generated/entity/services/apiService'; import { DashboardService } from '../../generated/entity/services/dashboardService'; import { DatabaseService } from '../../generated/entity/services/databaseService'; +import { IngestionPipeline } from '../../generated/entity/services/ingestionPipelines/ingestionPipeline'; import { MessagingService } from '../../generated/entity/services/messagingService'; import { MlmodelService } from '../../generated/entity/services/mlmodelService'; import { PipelineService } from '../../generated/entity/services/pipelineService'; import { SearchService } from '../../generated/entity/services/searchService'; import { StorageService } from '../../generated/entity/services/storageService'; +import { Type } from '../../generated/entity/type'; import { TestCase } from '../../generated/tests/testCase'; +import { TestSuite } from '../../generated/tests/testSuite'; import { Aggregations, SearchResponse } from '../../interface/search.interface'; import { QueryFilterInterface } from '../../pages/ExplorePage/ExplorePage.interface'; import { SearchDropdownOption } from '../SearchDropdown/SearchDropdown.interface'; @@ -133,7 +139,13 @@ export type EntityUnion = | APIEndpoint | APIService | APICollection - | Metric; + | Metric + | Type + | TestSuite + | Kpi + | AppMarketPlaceDefinition + | IngestionPipeline + | Query; export type EntityWithServices = | Topic diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/PopOverCard/EntityPopOverCard.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/PopOverCard/EntityPopOverCard.test.tsx index 0f29b331801..a67764df53b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/PopOverCard/EntityPopOverCard.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/PopOverCard/EntityPopOverCard.test.tsx @@ -15,7 +15,32 @@ import { act, render, screen } from '@testing-library/react'; import { EntityType } from '../../../enums/entity.enum'; import { useApplicationStore } from '../../../hooks/useApplicationStore'; import { MOCK_TAG_DATA, MOCK_TAG_ENCODED_FQN } from '../../../mocks/Tags.mock'; +import { getAlertsFromName } from '../../../rest/alertsAPI'; +import { getApiCollectionByFQN } from '../../../rest/apiCollectionsAPI'; +import { getApiEndPointByFQN } from '../../../rest/apiEndpointsAPI'; +import { getApplicationByName } from '../../../rest/applicationAPI'; +import { getMarketPlaceApplicationByFqn } from '../../../rest/applicationMarketPlaceAPI'; +import { getChartByFqn } from '../../../rest/chartsAPI'; +import { getContract } from '../../../rest/contractAPI'; +import { getDataProductByName } from '../../../rest/dataProductAPI'; +import { getDomainByName } from '../../../rest/domainAPI'; +import { + getGlossariesByName, + getGlossaryTermByFQN, +} from '../../../rest/glossaryAPI'; +import { getIngestionPipelineByFqn } from '../../../rest/ingestionPipelineAPI'; +import { getKPIByName } from '../../../rest/KpiAPI'; +import { getTypeByFQN } from '../../../rest/metadataTypeAPI'; +import { getMetricByFqn } from '../../../rest/metricsAPI'; +import { getPersonaByName } from '../../../rest/PersonaAPI'; +import { getQueryByFqn } from '../../../rest/queryAPI'; +import { getPolicyByName, getRoleByName } from '../../../rest/rolesAPIV1'; +import { getSearchIndexDetailsByFQN } from '../../../rest/SearchIndexAPI'; +import { getServiceByFQN } from '../../../rest/serviceAPI'; import { getTagByFqn } from '../../../rest/tagAPI'; +import { getTeamByName } from '../../../rest/teamsAPI'; +import { getTestCaseByFqn, getTestSuiteByName } from '../../../rest/testAPI'; +import { getBotByName, getUserByName } from '../../../rest/userAPI'; import EntityPopOverCard, { PopoverContent } from './EntityPopOverCard'; const updateCachedEntityData = jest.fn(); @@ -103,6 +128,93 @@ jest.mock('../../../rest/topicsAPI', () => ({ getTopicByFqn: jest.fn().mockImplementation(() => Promise.resolve({})), })); +jest.mock('../../../rest/alertsAPI', () => ({ + getAlertsFromName: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/apiCollectionsAPI', () => ({ + getApiCollectionByFQN: jest + .fn() + .mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/apiEndpointsAPI', () => ({ + getApiEndPointByFQN: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/applicationAPI', () => ({ + getApplicationByName: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/applicationMarketPlaceAPI', () => ({ + getMarketPlaceApplicationByFqn: jest + .fn() + .mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/chartsAPI', () => ({ + getChartByFqn: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/contractAPI', () => ({ + getContract: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/KpiAPI', () => ({ + getKPIByName: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/metadataTypeAPI', () => ({ + getTypeByFQN: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/metricsAPI', () => ({ + getMetricByFqn: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/PersonaAPI', () => ({ + getPersonaByName: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/rolesAPIV1', () => ({ + getPolicyByName: jest.fn().mockImplementation(() => Promise.resolve({})), + getRoleByName: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/SearchIndexAPI', () => ({ + getSearchIndexDetailsByFQN: jest + .fn() + .mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/serviceAPI', () => ({ + getServiceByFQN: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/testAPI', () => ({ + getTestCaseByFqn: jest.fn().mockImplementation(() => Promise.resolve({})), + getTestSuiteByName: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/teamsAPI', () => ({ + getTeamByName: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/userAPI', () => ({ + getBotByName: jest.fn().mockImplementation(() => Promise.resolve({})), + getUserByName: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/queryAPI', () => ({ + getQueryByFqn: jest.fn().mockImplementation(() => Promise.resolve({})), +})); + +jest.mock('../../../rest/ingestionPipelineAPI', () => ({ + getIngestionPipelineByFqn: jest + .fn() + .mockImplementation(() => Promise.resolve({})), +})); + jest.mock('../../../hooks/useApplicationStore', () => ({ useApplicationStore: jest.fn().mockImplementation(() => ({ cachedEntityData: {}, @@ -111,6 +223,15 @@ jest.mock('../../../hooks/useApplicationStore', () => ({ })); describe('Test EntityPopoverCard component', () => { + beforeEach(() => { + updateCachedEntityData.mockClear(); + + (useApplicationStore as unknown as jest.Mock).mockImplementation(() => ({ + cachedEntityData: {}, + updateCachedEntityData, + })); + }); + it('EntityPopoverCard should render element', () => { render( { expect(mockTagAPI.mock.calls).toEqual([]); expect(screen.getByText('ExploreSearchCard')).toBeInTheDocument(); }); + + it('EntityPopoverCard should call bot API if entity type is BOT', async () => { + const mockBotFQN = 'test-bot'; + + await act(async () => { + render( + + ); + }); + + expect(getBotByName).toHaveBeenCalledWith(mockBotFQN, { + fields: [EntityType.BOT], + }); + }); + + it('EntityPopoverCard should call alerts API if entity type is EVENT_SUBSCRIPTION', async () => { + const mockAlertFQN = 'test-alert'; + + await act(async () => { + render( + + ); + }); + + expect(getAlertsFromName).toHaveBeenCalledWith(mockAlertFQN); + }); + + it('EntityPopoverCard should call bot API and trigger updateCachedEntityData', async () => { + const mockBotFQN = 'test-bot'; + const mockBotData = { id: 'bot-id', name: 'test-bot' }; + + (getBotByName as jest.Mock).mockImplementationOnce(() => + Promise.resolve(mockBotData) + ); + + await act(async () => { + render( + + ); + }); + + expect(getBotByName).toHaveBeenCalledWith(mockBotFQN, { + fields: [EntityType.BOT], + }); + expect(updateCachedEntityData).toHaveBeenCalledWith({ + id: mockBotFQN, + entityDetails: mockBotData, + }); + }); + + it('EntityPopoverCard should call alerts API and trigger updateCachedEntityData', async () => { + const mockAlertFQN = 'test-alert'; + const mockAlertData = { id: 'alert-id', name: 'test-alert' }; + + (getAlertsFromName as jest.Mock).mockImplementationOnce(() => + Promise.resolve(mockAlertData) + ); + + await act(async () => { + render( + + ); + }); + + expect(getAlertsFromName).toHaveBeenCalledWith(mockAlertFQN); + expect(updateCachedEntityData).toHaveBeenCalledWith({ + id: mockAlertFQN, + entityDetails: mockAlertData, + }); + }); + + it('EntityPopoverCard should call role API if entity type is ROLE', async () => { + const mockRoleFQN = 'test-role'; + + await act(async () => { + render( + + ); + }); + + expect(getRoleByName).toHaveBeenCalledWith(mockRoleFQN, ''); + }); + + it('EntityPopoverCard should call role API and trigger updateCachedEntityData', async () => { + const mockRoleFQN = 'test-role'; + const mockRoleData = { id: 'role-id', name: 'test-role' }; + + (getRoleByName as jest.Mock).mockImplementationOnce(() => + Promise.resolve(mockRoleData) + ); + + await act(async () => { + render( + + ); + }); + + expect(getRoleByName).toHaveBeenCalledWith(mockRoleFQN, ''); + expect(updateCachedEntityData).toHaveBeenCalledWith({ + id: mockRoleFQN, + entityDetails: mockRoleData, + }); + }); + + it('EntityPopoverCard should call policy API if entity type is POLICY', async () => { + const mockPolicyFQN = 'test-policy'; + + await act(async () => { + render( + + ); + }); + + expect(getPolicyByName).toHaveBeenCalledWith(mockPolicyFQN, ''); + }); + + it('EntityPopoverCard should call policy API and trigger updateCachedEntityData', async () => { + const mockPolicyFQN = 'test-policy'; + const mockPolicyData = { id: 'policy-id', name: 'test-policy' }; + + (getPolicyByName as jest.Mock).mockImplementationOnce(() => + Promise.resolve(mockPolicyData) + ); + + await act(async () => { + render( + + ); + }); + + expect(getPolicyByName).toHaveBeenCalledWith(mockPolicyFQN, ''); + expect(updateCachedEntityData).toHaveBeenCalledWith({ + id: mockPolicyFQN, + entityDetails: mockPolicyData, + }); + }); + + it('EntityPopoverCard should call service API for all service types', async () => { + const serviceTypes = [ + EntityType.DATABASE_SERVICE, + EntityType.MESSAGING_SERVICE, + EntityType.DASHBOARD_SERVICE, + EntityType.PIPELINE_SERVICE, + EntityType.MLMODEL_SERVICE, + EntityType.STORAGE_SERVICE, + EntityType.SEARCH_SERVICE, + EntityType.API_SERVICE, + EntityType.SECURITY_SERVICE, + EntityType.METADATA_SERVICE, + EntityType.SERVICE, + ]; + + for (const serviceType of serviceTypes) { + const mockServiceFQN = `test-${serviceType}`; + + await act(async () => { + render( + + ); + }); + + expect(getServiceByFQN).toHaveBeenCalledWith(serviceType, mockServiceFQN); + } + }); + + it('EntityPopoverCard should call type API if entity type is TYPE', async () => { + const mockTypeFQN = 'test-type'; + + await act(async () => { + render( + + ); + }); + + expect(getTypeByFQN).toHaveBeenCalledWith(mockTypeFQN); + }); + + it('EntityPopoverCard should call team API if entity type is TEAM', async () => { + const mockTeamFQN = 'test-team'; + + await act(async () => { + render( + + ); + }); + + expect(getTeamByName).toHaveBeenCalledWith(mockTeamFQN); + }); + + it('EntityPopoverCard should call user API if entity type is USER', async () => { + const mockUserFQN = 'test-user'; + + await act(async () => { + render( + + ); + }); + + expect(getUserByName).toHaveBeenCalledWith(mockUserFQN); + }); + + it('EntityPopoverCard should call test suite API if entity type is TEST_SUITE', async () => { + const mockTestSuiteFQN = 'test-test-suite'; + + await act(async () => { + render( + + ); + }); + + expect(getTestSuiteByName).toHaveBeenCalledWith(mockTestSuiteFQN); + }); + + it('EntityPopoverCard should call KPI API if entity type is KPI', async () => { + const mockKPIFQN = 'test-kpi'; + + await act(async () => { + render( + + ); + }); + + expect(getKPIByName).toHaveBeenCalledWith(mockKPIFQN); + }); + + it('EntityPopoverCard should call search index API if entity type is SEARCH_INDEX', async () => { + const mockSearchIndexFQN = 'test-search-index'; + + await act(async () => { + render( + + ); + }); + + expect(getSearchIndexDetailsByFQN).toHaveBeenCalledWith(mockSearchIndexFQN); + }); + + it('EntityPopoverCard should call market place application API if entity type is APP_MARKET_PLACE_DEFINITION', async () => { + const mockAppFQN = 'test-app-market-place'; + + await act(async () => { + render( + + ); + }); + + expect(getMarketPlaceApplicationByFqn).toHaveBeenCalledWith(mockAppFQN); + }); + + it('EntityPopoverCard should call application API if entity type is APPLICATION', async () => { + const mockAppFQN = 'test-application'; + + await act(async () => { + render( + + ); + }); + + expect(getApplicationByName).toHaveBeenCalledWith(mockAppFQN); + }); + + it('EntityPopoverCard should call persona API if entity type is PERSONA', async () => { + const mockPersonaFQN = 'test-persona'; + + await act(async () => { + render( + + ); + }); + + expect(getPersonaByName).toHaveBeenCalledWith(mockPersonaFQN); + }); + + it('EntityPopoverCard should call ingestion pipeline API if entity type is INGESTION_PIPELINE', async () => { + const mockIngestionPipelineFQN = 'test-ingestion-pipeline'; + + await act(async () => { + render( + + ); + }); + + expect(getIngestionPipelineByFqn).toHaveBeenCalledWith( + mockIngestionPipelineFQN + ); + }); + + it('EntityPopoverCard should call contract API if entity type is DATA_CONTRACT', async () => { + const mockContractFQN = 'test-data-contract'; + + await act(async () => { + render( + + ); + }); + + expect(getContract).toHaveBeenCalledWith(mockContractFQN); + }); + + it('EntityPopoverCard should call query API if entity type is QUERY', async () => { + const mockQueryFQN = 'test-query'; + + await act(async () => { + render( + + ); + }); + + expect(getQueryByFqn).toHaveBeenCalledWith(mockQueryFQN); + }); + + it('EntityPopoverCard should call API collection API if entity type is API_COLLECTION', async () => { + const mockApiCollectionFQN = 'test-api-collection'; + + await act(async () => { + render( + + ); + }); + + expect(getApiCollectionByFQN).toHaveBeenCalledWith( + mockApiCollectionFQN, + expect.any(Object) + ); + }); + + it('EntityPopoverCard should call API endpoint API if entity type is API_ENDPOINT', async () => { + const mockApiEndpointFQN = 'test-api-endpoint'; + + await act(async () => { + render( + + ); + }); + + expect(getApiEndPointByFQN).toHaveBeenCalledWith( + mockApiEndpointFQN, + expect.any(Object) + ); + }); + + it('EntityPopoverCard should call metric API if entity type is METRIC', async () => { + const mockMetricFQN = 'test-metric'; + + await act(async () => { + render( + + ); + }); + + expect(getMetricByFqn).toHaveBeenCalledWith( + mockMetricFQN, + expect.any(Object) + ); + }); + + it('EntityPopoverCard should call chart API if entity type is CHART', async () => { + const mockChartFQN = 'test-chart'; + + await act(async () => { + render( + + ); + }); + + expect(getChartByFqn).toHaveBeenCalledWith( + mockChartFQN, + expect.any(Object) + ); + }); + + it('EntityPopoverCard should call domain API if entity type is DOMAIN', async () => { + const mockDomainFQN = 'test-domain'; + + await act(async () => { + render( + + ); + }); + + expect(getDomainByName).toHaveBeenCalledWith( + mockDomainFQN, + expect.any(Object) + ); + }); + + it('EntityPopoverCard should call data product API if entity type is DATA_PRODUCT', async () => { + const mockDataProductFQN = 'test-data-product'; + + await act(async () => { + render( + + ); + }); + + expect(getDataProductByName).toHaveBeenCalledWith( + mockDataProductFQN, + expect.any(Object) + ); + }); + + it('EntityPopoverCard should call glossary API if entity type is GLOSSARY', async () => { + const mockGlossaryFQN = 'test-glossary'; + + await act(async () => { + render( + + ); + }); + + expect(getGlossariesByName).toHaveBeenCalledWith( + mockGlossaryFQN, + expect.any(Object) + ); + }); + + it('EntityPopoverCard should call glossary term API if entity type is GLOSSARY_TERM', async () => { + const mockGlossaryTermFQN = 'test-glossary-term'; + + await act(async () => { + render( + + ); + }); + + expect(getGlossaryTermByFQN).toHaveBeenCalledWith( + mockGlossaryTermFQN, + expect.any(Object) + ); + }); + + it('EntityPopoverCard should call test case API if entity type is TEST_CASE', async () => { + const mockTestCaseFQN = 'test-test-case'; + + await act(async () => { + render( + + ); + }); + + expect(getTestCaseByFqn).toHaveBeenCalledWith( + mockTestCaseFQN, + expect.any(Object) + ); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/PopOverCard/EntityPopOverCard.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/PopOverCard/EntityPopOverCard.tsx index 8b42221257a..12616bd5d51 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/PopOverCard/EntityPopOverCard.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/PopOverCard/EntityPopOverCard.tsx @@ -27,9 +27,13 @@ import { EntityType, TabSpecificField } from '../../../enums/entity.enum'; import { Table } from '../../../generated/entity/data/table'; import { Include } from '../../../generated/type/include'; import { useApplicationStore } from '../../../hooks/useApplicationStore'; +import { getAlertsFromName } from '../../../rest/alertsAPI'; import { getApiCollectionByFQN } from '../../../rest/apiCollectionsAPI'; import { getApiEndPointByFQN } from '../../../rest/apiEndpointsAPI'; +import { getApplicationByName } from '../../../rest/applicationAPI'; +import { getMarketPlaceApplicationByFqn } from '../../../rest/applicationMarketPlaceAPI'; import { getChartByFqn } from '../../../rest/chartsAPI'; +import { getContract } from '../../../rest/contractAPI'; import { getDashboardByFqn } from '../../../rest/dashboardAPI'; import { getDatabaseDetailsByFQN, @@ -42,15 +46,25 @@ import { getGlossariesByName, getGlossaryTermByFQN, } from '../../../rest/glossaryAPI'; +import { getIngestionPipelineByFqn } from '../../../rest/ingestionPipelineAPI'; +import { getKPIByName } from '../../../rest/KpiAPI'; +import { getTypeByFQN } from '../../../rest/metadataTypeAPI'; import { getMetricByFqn } from '../../../rest/metricsAPI'; import { getMlModelByFQN } from '../../../rest/mlModelAPI'; +import { getPersonaByName } from '../../../rest/PersonaAPI'; import { getPipelineByFqn } from '../../../rest/pipelineAPI'; +import { getQueryByFqn } from '../../../rest/queryAPI'; +import { getPolicyByName, getRoleByName } from '../../../rest/rolesAPIV1'; +import { getSearchIndexDetailsByFQN } from '../../../rest/SearchIndexAPI'; +import { getServiceByFQN } from '../../../rest/serviceAPI'; import { getContainerByFQN } from '../../../rest/storageAPI'; import { getStoredProceduresByFqn } from '../../../rest/storedProceduresAPI'; import { getTableDetailsByFQN } from '../../../rest/tableAPI'; -import { getTagByFqn } from '../../../rest/tagAPI'; -import { getTestCaseByFqn } from '../../../rest/testAPI'; +import { getClassificationByName, getTagByFqn } from '../../../rest/tagAPI'; +import { getTeamByName } from '../../../rest/teamsAPI'; +import { getTestCaseByFqn, getTestSuiteByName } from '../../../rest/testAPI'; import { getTopicByFqn } from '../../../rest/topicsAPI'; +import { getBotByName, getUserByName } from '../../../rest/userAPI'; import { getEntityName } from '../../../utils/EntityUtils'; import { EntityUnion } from '../../Explore/ExplorePage.interface'; import ExploreSearchCard from '../../ExploreV1/ExploreSearchCard/ExploreSearchCard'; @@ -211,6 +225,112 @@ export const PopoverContent: React.FC<{ break; + case EntityType.BOT: + promise = getBotByName(entityFQN, { + fields: [EntityType.BOT], + }); + + break; + + case EntityType.EVENT_SUBSCRIPTION: + promise = getAlertsFromName(entityFQN); + + break; + + case EntityType.ROLE: + promise = getRoleByName(entityFQN, ''); + + break; + + case EntityType.POLICY: + promise = getPolicyByName(entityFQN, ''); + + break; + + case EntityType.CLASSIFICATION: + promise = getClassificationByName(entityFQN); + + break; + + case EntityType.DATABASE_SERVICE: + case EntityType.MESSAGING_SERVICE: + case EntityType.DASHBOARD_SERVICE: + case EntityType.PIPELINE_SERVICE: + case EntityType.MLMODEL_SERVICE: + case EntityType.STORAGE_SERVICE: + case EntityType.SEARCH_SERVICE: + case EntityType.API_SERVICE: + case EntityType.SECURITY_SERVICE: + case EntityType.METADATA_SERVICE: + promise = getServiceByFQN(entityType, entityFQN); + + break; + + case EntityType.TYPE: + promise = getTypeByFQN(entityFQN); + + break; + + case EntityType.TEAM: + promise = getTeamByName(entityFQN); + + break; + + case EntityType.USER: + promise = getUserByName(entityFQN); + + break; + + case EntityType.TEST_SUITE: + promise = getTestSuiteByName(entityFQN); + + break; + + case EntityType.KPI: + promise = getKPIByName(entityFQN); + + break; + + case EntityType.SEARCH_INDEX: + promise = getSearchIndexDetailsByFQN(entityFQN); + + break; + + case EntityType.APP_MARKET_PLACE_DEFINITION: + promise = getMarketPlaceApplicationByFqn(entityFQN); + + break; + + case EntityType.APPLICATION: + promise = getApplicationByName(entityFQN); + + break; + + case EntityType.PERSONA: + promise = getPersonaByName(entityFQN); + + break; + + case EntityType.INGESTION_PIPELINE: + promise = getIngestionPipelineByFqn(entityFQN); + + break; + + case EntityType.SERVICE: + promise = getServiceByFQN(EntityType.SERVICE, entityFQN); + + break; + + case EntityType.DATA_CONTRACT: + promise = getContract(entityFQN); + + break; + + case EntityType.QUERY: + promise = getQueryByFqn(entityFQN); + + break; + default: break; } diff --git a/openmetadata-ui/src/main/resources/ui/src/rest/contractAPI.ts b/openmetadata-ui/src/main/resources/ui/src/rest/contractAPI.ts index 33aeac25386..da5b041dc53 100644 --- a/openmetadata-ui/src/main/resources/ui/src/rest/contractAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/rest/contractAPI.ts @@ -49,7 +49,7 @@ export const listContracts = async (params: ListContractsParams) => { export const getContract = async (fqn: string) => { const response = await APIClient.get( - `/data-contracts/${fqn}` + `/dataContracts/name/${fqn}` ); return response.data; diff --git a/openmetadata-ui/src/main/resources/ui/src/rest/queryAPI.ts b/openmetadata-ui/src/main/resources/ui/src/rest/queryAPI.ts index d503a18cc41..0e9ca60244f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/rest/queryAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/rest/queryAPI.ts @@ -18,6 +18,7 @@ import { QueryVote } from '../components/Database/TableQueries/TableQueries.inte import { CreateQuery } from '../generated/api/data/createQuery'; import { Query } from '../generated/entity/data/query'; import { ListParams } from '../interface/API.interface'; +import { getEncodedFqn } from '../utils/StringsUtils'; import APIClient from './index'; export type ListQueriesParams = ListParams & { @@ -43,6 +44,17 @@ export const getQueryById = async (id: string, params?: QueryByIdParams) => { return response.data; }; +export const getQueryByFqn = async (fqn: string, params?: QueryByIdParams) => { + const response = await APIClient.get( + `${BASE_URL}/name/${getEncodedFqn(fqn)}`, + { + params, + } + ); + + return response.data; +}; + export const postQuery = async (query: CreateQuery) => { const response = await APIClient.post>( BASE_URL, diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/EntityUtilClassBase.ts b/openmetadata-ui/src/main/resources/ui/src/utils/EntityUtilClassBase.ts index ea263d08ef1..49ef4a4b5f2 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/EntityUtilClassBase.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/EntityUtilClassBase.ts @@ -67,10 +67,12 @@ import { } from './EntityUtils.interface'; import { getApplicationDetailsPath, + getBotsPath, getDomainDetailsPath, getEditWebhookPath, getEntityDetailsPath, getGlossaryTermDetailsPath, + getKpiPath, getNotificationAlertDetailsPath, getObservabilityAlertDetailsPath, getPersonaDetailsPath, @@ -318,6 +320,12 @@ class EntityUtilClassBase { subTab ); + case EntityType.BOT: + return getBotsPath(fullyQualifiedName); + + case EntityType.KPI: + return getKpiPath(fullyQualifiedName); + case SearchIndex.TABLE: case EntityType.TABLE: default: