diff --git a/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/custom_no_data_page/custom_no_data_page.cy.ts b/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/custom_no_data_page/custom_no_data_page.cy.ts deleted file mode 100644 index a246a2ccb7c34..0000000000000 --- a/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/custom_no_data_page/custom_no_data_page.cy.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -describe('Custom no data page', () => { - beforeEach(() => { - cy.loginAsEditorUser(); - }); - - before(() => { - // make sure entity centric experience is disabled - cy.updateAdvancedSettings({ - 'observability:entityCentricExperience': false, - }); - }); - - after(() => { - cy.updateAdvancedSettings({ - 'observability:entityCentricExperience': false, - }); - }); - - it('shows the default no data screen when entity centric experience is disabled ', () => { - cy.visitKibana('/app/apm'); - cy.contains('Welcome to Elastic Observability!'); - }); - - it('shows the custom no data screen when entity centric experience is enabled', () => { - cy.updateAdvancedSettings({ - 'observability:entityCentricExperience': true, - }); - cy.visitKibana('/app/apm'); - cy.contains('Welcome to Elastic Observability!').should('not.exist'); - cy.contains('Detect and resolve problems with your application'); - cy.contains('Try collecting services from logs'); - }); -}); diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/service_inventory/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/service_inventory/index.tsx index e30c79eb483f7..55f72d21f48d7 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/service_inventory/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/service_inventory/index.tsx @@ -5,40 +5,8 @@ * 2.0. */ import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiEmptyPrompt, EuiLoadingLogo } from '@elastic/eui'; -import { isEmpty } from 'lodash'; import { ApmServiceInventory } from './apm_signal_inventory'; -import { MultiSignalInventory } from './multi_signal_inventory'; -import { useApmParams } from '../../../hooks/use_apm_params'; -import { useEntityManagerEnablementContext } from '../../../context/entity_manager_context/use_entity_manager_enablement_context'; export function ServiceInventory() { - const { isEnablementPending, isEntityCentricExperienceViewEnabled } = - useEntityManagerEnablementContext(); - - const { - query: { serviceGroup }, - } = useApmParams('/services'); - - if (isEnablementPending) { - return ( - } - title={ -

- {i18n.translate('xpack.apm.loadingService', { - defaultMessage: 'Loading services', - })} -

- } - /> - ); - } - - return isEntityCentricExperienceViewEnabled && isEmpty(serviceGroup) ? ( - - ) : ( - - ); + return ; } diff --git a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template/entities_inventory_callout.tsx b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template/entities_inventory_callout.tsx new file mode 100644 index 0000000000000..16cc93e2827f2 --- /dev/null +++ b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template/entities_inventory_callout.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiToolTip, EuiButtonIcon } from '@elastic/eui'; +import { TechnicalPreviewBadge } from '@kbn/observability-shared-plugin/public'; +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { ApmPluginStartDeps } from '../../../../plugin'; + +interface EntitiesInventoryCalloutProps { + onDissmiss: () => void; +} + +export function EntitiesInventoryCallout({ onDissmiss }: EntitiesInventoryCalloutProps) { + const { services } = useKibana(); + const { observabilityShared } = services; + + const entitiesInventoryLocator = observabilityShared.locators.entitiesInventory; + + return ( + + + + + + + + + + + + } + > + + + + + ); +} diff --git a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template.tsx b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template/index.tsx similarity index 63% rename from x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template.tsx rename to x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template/index.tsx index fca4f3809edb5..8633e206599b6 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_main_template/index.tsx @@ -11,24 +11,22 @@ import { entityCentricExperience } from '@kbn/observability-plugin/common'; import { ObservabilityPageTemplateProps } from '@kbn/observability-shared-plugin/public'; import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; import React, { useContext } from 'react'; -import { i18n } from '@kbn/i18n'; import { useLocation } from 'react-router-dom'; import { FeatureFeedbackButton } from '@kbn/observability-shared-plugin/public'; -import { useEntityManagerEnablementContext } from '../../../context/entity_manager_context/use_entity_manager_enablement_context'; -import { useDefaultAiAssistantStarterPromptsForAPM } from '../../../hooks/use_default_ai_assistant_starter_prompts_for_apm'; -import { KibanaEnvironmentContext } from '../../../context/kibana_environment_context/kibana_environment_context'; -import { getPathForFeedback } from '../../../utils/get_path_for_feedback'; -import { EnvironmentsContextProvider } from '../../../context/environments_context/environments_context'; -import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher'; -import { ApmPluginStartDeps } from '../../../plugin'; -import { ServiceGroupSaveButton } from '../../app/service_groups'; -import { ServiceGroupsButtonGroup } from '../../app/service_groups/service_groups_button_group'; -import { ApmEnvironmentFilter } from '../../shared/environment_filter'; -import { getNoDataConfig } from './no_data_config'; -import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; -import { EntityEnablement } from '../../shared/entity_enablement'; -import { CustomNoDataTemplate } from './custom_no_data_template'; -import { ServiceInventoryView } from '../../../context/entity_manager_context/entity_manager_context'; +import { useLocalStorage } from '../../../../hooks/use_local_storage'; +import { useEntityManagerEnablementContext } from '../../../../context/entity_manager_context/use_entity_manager_enablement_context'; +import { useDefaultAiAssistantStarterPromptsForAPM } from '../../../../hooks/use_default_ai_assistant_starter_prompts_for_apm'; +import { KibanaEnvironmentContext } from '../../../../context/kibana_environment_context/kibana_environment_context'; +import { getPathForFeedback } from '../../../../utils/get_path_for_feedback'; +import { EnvironmentsContextProvider } from '../../../../context/environments_context/environments_context'; +import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; +import { ApmPluginStartDeps } from '../../../../plugin'; +import { ServiceGroupSaveButton } from '../../../app/service_groups'; +import { ServiceGroupsButtonGroup } from '../../../app/service_groups/service_groups_button_group'; +import { ApmEnvironmentFilter } from '../../../shared/environment_filter'; +import { getNoDataConfig } from '../no_data_config'; +import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context'; +import { EntitiesInventoryCallout } from './entities_inventory_callout'; // Paths that must skip the no data screen const bypassNoDataScreenPaths = ['/settings', '/diagnostics']; @@ -78,8 +76,8 @@ export function ApmMainTemplate({ entityCentricExperience, true ); - const { isEntityCentricExperienceViewEnabled, serviceInventoryViewLocalStorageSetting } = - useEntityManagerEnablementContext(); + + const { isEntityCentricExperienceViewEnabled } = useEntityManagerEnablementContext(); const ObservabilityPageTemplate = observabilityShared.navigation.PageTemplate; @@ -117,11 +115,6 @@ export function ApmMainTemplate({ const hasApmData = !!data?.hasData; const hasApmIntegrations = !!fleetApmPoliciesData?.hasApmPolicies; - const showCustomEmptyState = - !hasApmData && - !isLoading && - isEntityCentricExperienceSettingEnabled && - serviceInventoryViewLocalStorageSetting === ServiceInventoryView.classic; const noDataConfig = getNoDataConfig({ basePath, @@ -142,6 +135,7 @@ export function ApmMainTemplate({ const rightSideItems = [...(showServiceGroupSaveButton ? [] : [])]; const sanitizedPath = getPathForFeedback(window.location.pathname); + const pageHeaderTitle = ( {pageHeader?.pageTitle ?? pageTitle} @@ -168,47 +162,44 @@ export function ApmMainTemplate({ ); - const pageTemplate = showCustomEmptyState ? ( - - ) : ( - - {isEntityCentricExperienceSettingEnabled && - showEnablementCallout && - selectedNavButton === 'allServices' ? ( - - ) : null} - {showServiceGroupsNav && selectedNavButton && ( - - )} - - ), - }} - {...pageTemplateProps} - > - {children} - + const [dismissedEntitiesInventoryCallout, setdismissedEntitiesInventoryCallout] = useLocalStorage( + `apm.dismissedEntitiesInventoryCallout`, + false ); - return {pageTemplate}; + const showEntitiesInventoryCallout = + !dismissedEntitiesInventoryCallout && + isEntityCentricExperienceSettingEnabled && + selectedNavButton !== undefined; + + return ( + + + {showEntitiesInventoryCallout ? ( + { + setdismissedEntitiesInventoryCallout(true); + }} + /> + ) : null} + {showServiceGroupsNav && selectedNavButton && ( + + )} + + ), + }} + {...pageTemplateProps} + > + {children} + + + ); } diff --git a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/custom_no_data_template.tsx b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/custom_no_data_template.tsx deleted file mode 100644 index d006e43c3971b..0000000000000 --- a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/custom_no_data_template.tsx +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiFlexGroup, - EuiFlexItem, - EuiSpacer, - EuiTextColor, - EuiText, - EuiButton, - EuiPageTemplate, - EuiCard, - EuiImage, - EuiScreenReaderOnly, -} from '@elastic/eui'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution'; -import { NoDataConfig } from '@kbn/shared-ux-page-no-data-config-types'; -import { ApmPluginStartDeps } from '../../../plugin'; -import { EntityEnablement } from '../../shared/entity_enablement'; - -export function CustomNoDataTemplate({ - isPageDataLoaded, - noDataConfig, -}: { - isPageDataLoaded: boolean; - noDataConfig?: NoDataConfig; -}) { - const { services } = useKibana(); - const { http, observabilityShared } = services; - const basePath = http?.basePath.get(); - - const ObservabilityPageTemplate = observabilityShared.navigation.PageTemplate; - const imageUrl = `${basePath}/plugins/kibanaReact/assets/elastic_agent_card.svg`; - - return ( - - - - - - -

- {i18n.translate('xpack.apm.customEmtpyState.title', { - defaultMessage: 'Detect and resolve problems with your application', - })} -

- -

- {i18n.translate('xpack.apm.customEmtpyState.description', { - defaultMessage: - 'Start collecting data for your applications and services so you can detect and resolve problems faster.', - })} -

-
-
- - - - {i18n.translate('xpack.apm.customEmtpyState.title.reader', { - defaultMessage: 'Add APM data', - })} - - - } - description={i18n.translate('xpack.apm.customEmtpyState.card.description', { - defaultMessage: - 'Use APM agents to collect APM data. We make it easy with agents for many popular languages.', - })} - footer={ - - - - {noDataConfig?.action.elasticAgent.title} - - - -

- -

-
-
-
- } - image={ - - } - /> -
-
-
- ); -} diff --git a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/service_group_template.tsx b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/service_group_template.tsx index 67695c6485006..d9fb2437be14c 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/service_group_template.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/service_group_template.tsx @@ -20,8 +20,6 @@ import { useApmRouter } from '../../../hooks/use_apm_router'; import { useAnyOfApmParams } from '../../../hooks/use_apm_params'; import { ApmMainTemplate } from './apm_main_template'; import { useBreadcrumb } from '../../../context/breadcrumbs/use_breadcrumb'; -import { TechnicalPreviewBadge } from '../../shared/technical_preview_badge'; -import { useEntityManagerEnablementContext } from '../../../context/entity_manager_context/use_entity_manager_enablement_context'; export function ServiceGroupTemplate({ pageTitle, @@ -165,7 +163,6 @@ type ServiceGroupContextTab = NonNullable[0] & { function useTabs(selectedTab: ServiceGroupContextTab['key']) { const router = useApmRouter(); const { query } = useAnyOfApmParams('/services', '/service-map'); - const { isEntityCentricExperienceViewEnabled } = useEntityManagerEnablementContext(); const tabs: ServiceGroupContextTab[] = [ { @@ -180,11 +177,6 @@ function useTabs(selectedTab: ServiceGroupContextTab['key']) { defaultMessage: 'Inventory', })} - - {isEntityCentricExperienceViewEnabled && ( - - )} - ), href: router.link('/services', { query }), diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/entity_enablement/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/entity_enablement/index.tsx deleted file mode 100644 index 62f5cf708bcf7..0000000000000 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/entity_enablement/index.tsx +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useState } from 'react'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import useToggle from 'react-use/lib/useToggle'; -import { - EuiButtonIcon, - EuiFlexGroup, - EuiFlexItem, - EuiLink, - EuiLoadingSpinner, - EuiPopover, - EuiPopoverFooter, - EuiSkeletonText, - EuiText, - EuiTextColor, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import type { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; -import { EntityManagerUnauthorizedError } from '@kbn/entityManager-plugin/public'; -import { TechnicalPreviewBadge } from '../technical_preview_badge'; -import { ApmPluginStartDeps } from '../../../plugin'; -import { useEntityManagerEnablementContext } from '../../../context/entity_manager_context/use_entity_manager_enablement_context'; -import { FeedbackModal } from './feedback_modal'; -import { ServiceInventoryView } from '../../../context/entity_manager_context/entity_manager_context'; -import { Unauthorized } from './unauthorized_modal'; -import { useLocalStorage } from '../../../hooks/use_local_storage'; - -export function EntityEnablement({ label, tooltip }: { label: string; tooltip?: string }) { - const [isFeedbackModalVisible, setsIsFeedbackModalVisible] = useLocalStorage( - 'apm.isFeedbackModalVisible', - undefined - ); - - const [isUnauthorizedModalVisible, setsIsUnauthorizedModalVisible] = useState(false); - - const { - services: { entityManager }, - notifications, - } = useKibana(); - - const { - isEntityManagerEnabled, - isEnablementPending, - refetch, - setServiceInventoryViewLocalStorageSetting, - isEntityCentricExperienceViewEnabled, - tourState, - updateTourState, - } = useEntityManagerEnablementContext(); - - const [isPopoverOpen, togglePopover] = useToggle(false); - const [isLoading, setIsLoading] = useToggle(false); - - const handleRestoreView = async () => { - setServiceInventoryViewLocalStorageSetting(ServiceInventoryView.classic); - if (isFeedbackModalVisible === undefined) { - setsIsFeedbackModalVisible(true); - } - }; - - const handleEnablement = async () => { - if (isEntityManagerEnabled) { - setServiceInventoryViewLocalStorageSetting(ServiceInventoryView.entity); - if (tourState.isModalVisible === undefined) { - updateTourState({ isModalVisible: true }); - } - return; - } - - setIsLoading(true); - try { - const response = await entityManager.entityClient.enableManagedEntityDiscovery(); - if (response.success) { - setIsLoading(false); - setServiceInventoryViewLocalStorageSetting(ServiceInventoryView.entity); - - if (tourState.isModalVisible === undefined) { - updateTourState({ isModalVisible: true }); - } - refetch(); - } else { - throw new Error(response.message); - } - } catch (error) { - setIsLoading(false); - - if (error instanceof EntityManagerUnauthorizedError) { - setsIsUnauthorizedModalVisible(true); - return; - } - - const err = error as Error | IHttpFetchError; - notifications.toasts.danger({ - title: i18n.translate('xpack.apm.eemEnablement.errorTitle', { - defaultMessage: 'Error while enabling the new experience', - }), - body: 'response' in err ? err.body?.message ?? err.response?.statusText : err.message, - }); - } - }; - - const handleOnCloseFeedback = () => { - setsIsFeedbackModalVisible(false); - }; - - return isEnablementPending ? ( - - - - ) : ( - - - {isLoading ? ( - - ) : ( - - )} - - - - {isEntityCentricExperienceViewEnabled - ? i18n.translate('xpack.apm.eemEnablement.enabled.', { - defaultMessage: 'Viewing our new experience', - }) - : label} - - - {tooltip && ( - - - } - isOpen={isPopoverOpen} - closePopover={togglePopover} - anchorPosition="downLeft" - > -
- -

- {i18n.translate('xpack.apm.entityEnablement.content', { - defaultMessage: - 'Our new experience combines both APM-instrumented services with services detected from logs in a single service inventory.', - })} -

-
-
- - - - {i18n.translate('xpack.apm.entityEnablement.footer', { - defaultMessage: 'Learn more', - })} - - - -
-
- )} - {isEntityCentricExperienceViewEnabled && ( - - - {i18n.translate('xpack.apm.eemEnablement.restoreClassicView.', { - defaultMessage: 'Restore classic view', - })} - - - )} - - setsIsUnauthorizedModalVisible(false)} - label={label} - /> -
- ); -} diff --git a/x-pack/plugins/observability_solution/apm/public/context/entity_manager_context/entity_manager_context.tsx b/x-pack/plugins/observability_solution/apm/public/context/entity_manager_context/entity_manager_context.tsx index 93205c907caa0..95a246ddce566 100644 --- a/x-pack/plugins/observability_solution/apm/public/context/entity_manager_context/entity_manager_context.tsx +++ b/x-pack/plugins/observability_solution/apm/public/context/entity_manager_context/entity_manager_context.tsx @@ -62,11 +62,6 @@ export function EntityManagerEnablementContextProvider({ true ); - const isEntityCentricExperienceViewEnabled = - isEntityManagerEnabled && - serviceInventoryViewLocalStorageSetting === ServiceInventoryView.entity && - isEntityCentricExperienceSettingEnabled; - function handleServiceInventoryViewChange(nextView: ServiceInventoryView) { setServiceInventoryViewLocalStorageSetting(nextView); // Updates the telemetry context variable every time the user switches views @@ -88,7 +83,7 @@ export function EntityManagerEnablementContextProvider({ refetch, serviceInventoryViewLocalStorageSetting, setServiceInventoryViewLocalStorageSetting: handleServiceInventoryViewChange, - isEntityCentricExperienceViewEnabled, + isEntityCentricExperienceViewEnabled: isEntityCentricExperienceSettingEnabled, tourState, updateTourState: handleTourStateUpdate, }} diff --git a/x-pack/plugins/observability_solution/apm/tsconfig.json b/x-pack/plugins/observability_solution/apm/tsconfig.json index 9195c2547a71a..6f3ff13a2af3e 100644 --- a/x-pack/plugins/observability_solution/apm/tsconfig.json +++ b/x-pack/plugins/observability_solution/apm/tsconfig.json @@ -120,10 +120,6 @@ "@kbn/test-jest-helpers", "@kbn/security-plugin-types-common", "@kbn/entityManager-plugin", - "@kbn/react-hooks", - "@kbn/shared-ux-avatar-solution", - "@kbn/shared-ux-page-no-data-config-types", - "@kbn/react-hooks", "@kbn/server-route-repository-utils", "@kbn/core-analytics-browser", "@kbn/apm-types", @@ -131,6 +127,7 @@ "@kbn/serverless", "@kbn/aiops-log-rate-analysis", "@kbn/router-utils", + "@kbn/react-hooks", ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/inventory/public/types.ts b/x-pack/plugins/observability_solution/inventory/public/types.ts index ed4a500edca68..2393b1b55e2b6 100644 --- a/x-pack/plugins/observability_solution/inventory/public/types.ts +++ b/x-pack/plugins/observability_solution/inventory/public/types.ts @@ -13,10 +13,10 @@ import { EntityManagerPublicPluginStart, } from '@kbn/entityManager-plugin/public'; import type { InferencePublicStart, InferencePublicSetup } from '@kbn/inference-plugin/public'; +import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; -import type { SharePluginStart } from '@kbn/share-plugin/public'; /* eslint-disable @typescript-eslint/no-empty-interface*/ @@ -25,6 +25,7 @@ export interface ConfigSchema {} export interface InventorySetupDependencies { observabilityShared: ObservabilitySharedPluginSetup; inference: InferencePublicSetup; + share: SharePluginSetup; data: DataPublicPluginSetup; entityManager: EntityManagerPublicPluginSetup; } diff --git a/x-pack/plugins/observability_solution/observability_shared/common/index.ts b/x-pack/plugins/observability_solution/observability_shared/common/index.ts index d845ea1d398fd..d13e2b32839d6 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/index.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/index.ts @@ -178,6 +178,7 @@ export type { ServiceEntityLocatorParams, TransactionDetailsByTraceIdLocator, TransactionDetailsByTraceIdLocatorParams, + EntitiesInventoryLocator, } from './locators'; export { @@ -201,6 +202,8 @@ export { SERVICE_ENTITY_LOCATOR, TransactionDetailsByTraceIdLocatorDefinition, TRANSACTION_DETAILS_BY_TRACE_ID_LOCATOR, + EntitiesInventoryLocatorDefinition, + ENTITIES_INVENTORY_LOCATOR_ID, } from './locators'; export { COMMON_OBSERVABILITY_GROUPING } from './embeddable_grouping'; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/locators/entity_inventory/entity_inventory_locator.ts b/x-pack/plugins/observability_solution/observability_shared/common/locators/entity_inventory/entity_inventory_locator.ts new file mode 100644 index 0000000000000..deb820b0d5e0a --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_shared/common/locators/entity_inventory/entity_inventory_locator.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { SerializableRecord } from '@kbn/utility-types'; +import { LocatorDefinition, LocatorPublic } from '@kbn/share-plugin/common'; + +export type EntitiesInventoryLocator = LocatorPublic; + +export const ENTITIES_INVENTORY_LOCATOR_ID = 'ENTITY_INVENTORY_LOCATOR'; + +export class EntitiesInventoryLocatorDefinition implements LocatorDefinition { + public readonly id = ENTITIES_INVENTORY_LOCATOR_ID; + + public readonly getLocation = async () => { + return { + app: 'observability', + path: `/inventory`, + state: {}, + }; + }; +} diff --git a/x-pack/plugins/observability_solution/observability_shared/common/locators/index.ts b/x-pack/plugins/observability_solution/observability_shared/common/locators/index.ts index 9c5ded4940d5a..34a6ff391d672 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/locators/index.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/locators/index.ts @@ -17,3 +17,4 @@ export * from './infra/metrics_explorer_locator'; export * from './profiling/flamegraph_locator'; export * from './profiling/stacktraces_locator'; export * from './profiling/topn_functions_locator'; +export * from './entity_inventory/entity_inventory_locator'; diff --git a/x-pack/plugins/observability_solution/observability_shared/public/plugin.ts b/x-pack/plugins/observability_solution/observability_shared/public/plugin.ts index 7cd63d7be7602..7a131a2686ad0 100644 --- a/x-pack/plugins/observability_solution/observability_shared/public/plugin.ts +++ b/x-pack/plugins/observability_solution/observability_shared/public/plugin.ts @@ -45,6 +45,8 @@ import { type MetricsExplorerLocator, type ServiceEntityLocator, type TransactionDetailsByTraceIdLocator, + type EntitiesInventoryLocator, + EntitiesInventoryLocatorDefinition, } from '../common'; import { updateGlobalNavigation } from './services/update_global_navigation'; export interface ObservabilitySharedSetup { @@ -82,6 +84,7 @@ interface ObservabilitySharedLocators { transactionDetailsByTraceId: TransactionDetailsByTraceIdLocator; serviceEntity: ServiceEntityLocator; }; + entitiesInventory: EntitiesInventoryLocator; } export class ObservabilitySharedPlugin implements Plugin { @@ -159,6 +162,7 @@ export class ObservabilitySharedPlugin implements Plugin { ), serviceEntity: urlService.locators.create(new ServiceEntityLocatorDefinition()), }, + entitiesInventory: urlService.locators.create(new EntitiesInventoryLocatorDefinition()), }; } }