[APM] Fix link to onboarding page in the Observability Onboarding plugin (#161847)

Closes https://github.com/elastic/kibana/issues/159675

## Summary

We have in lot of places, Tutorial link hardcoded to
`'/app/home#/tutorial/apm'`

This must change based on deployment type to be Serverless or Non
Serverless.

For Serverless the URL is - `'/app/apm/onboarding'`
For Non Serverless, the URL - `'/app/home#/tutorial/apm'`

Hence to avoid adding logic to read Serverless/Non Serverless mode in
all plugins and packages, i have implemented a redirect URL
`/app/apm/tutorial` inside the APM plugin which will read the Serverless
config and accordingly do the redirect.
This commit is contained in:
Achyut Jhunjhunwala 2023-07-20 12:33:42 +02:00 committed by GitHub
parent ab486aff05
commit fabb7109a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 103 additions and 29 deletions

View file

@ -196,8 +196,8 @@ exports[`guide cards snapshots should render all cards 1`] = `
Object {
"icon": "apmTrace",
"navigateTo": Object {
"appId": "home",
"path": "#/tutorial/apm",
"appId": "apm",
"path": "/tutorial",
},
"order": 5,
"solution": "observability",

View file

@ -123,8 +123,8 @@ export const guideCards: GuideCardConstants[] = [
/>
),
navigateTo: {
appId: 'home',
path: '#/tutorial/apm',
appId: 'apm',
path: '/tutorial',
},
telemetryId: 'onboarding--observability--apm',
order: 5,

View file

@ -15,7 +15,7 @@ import { ApmPluginStartDeps } from '../../plugin';
function StepComponent() {
const { http } = useKibana<ApmPluginStartDeps>().services;
const installApmAgentLink = http?.basePath.prepend('/app/home#/tutorial/apm');
const installApmAgentLink = http?.basePath.prepend('/app/apm/tutorial');
return (
<>

View file

@ -18,6 +18,7 @@ import { serviceDetailRoute } from './service_detail';
import { mobileServiceDetailRoute } from './mobile_service_detail';
import { settingsRoute } from './settings';
import { onboarding } from './onboarding';
import { tutorialRedirectRoute } from './onboarding/redirect';
import { ApmMainTemplate } from './templates/apm_main_template';
import { ServiceGroupsList } from '../app/service_groups';
import { offsetRt } from '../../../common/comparison_rt';
@ -106,6 +107,7 @@ const apmRoutes = {
]),
}),
},
...tutorialRedirectRoute,
...onboarding,
...diagnosticsRoute,
...settingsRoute,

View file

@ -77,7 +77,7 @@ export function ApmHeaderActionMenu() {
)}
<EuiHeaderLink
color="primary"
href={kibanaHref('/app/home#/tutorial/apm')}
href={kibanaHref('/app/apm/tutorial')}
iconType="indexOpen"
data-test-subj="apmAddDataHeaderLink"
>

View file

@ -0,0 +1,37 @@
/*
* 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 from 'react';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
function TutorialRedirect() {
const {
config: { serverlessOnboarding },
core: {
application: { navigateToApp },
},
} = useApmPluginContext();
if (serverlessOnboarding) {
navigateToApp('apm', {
path: '/onboarding',
replace: true,
});
} else {
navigateToApp('home', {
path: '#/tutorial/apm',
replace: true,
});
}
return <></>;
}
export const tutorialRedirectRoute = {
'/tutorial': {
element: <TutorialRedirect />,
},
};

View file

@ -43,7 +43,7 @@ function getNoDataConfigDetails({
if (hasApmIntegrations) {
return {
title: addDataTitle,
href: `${basePath}/app/home#/tutorial/apm`,
href: `${basePath}/app/apm/tutorial`,
description,
};
}

View file

@ -31,7 +31,7 @@ export function SetupInstructionsLink({
return (
<EuiLink
data-test-subj="apmSetupInstructionsLinkLink"
href={core.http.basePath.prepend('/app/home#/tutorial/apm')}
href={core.http.basePath.prepend('/app/apm/tutorial')}
>
{buttonFill ? (
<EuiButton

View file

@ -171,12 +171,20 @@ const apmStorageExplorerTitle = i18n.translate(
}
);
const apmTutorialTitle = i18n.translate(
'xpack.apm.navigation.apmTutorialTitle',
{
defaultMessage: 'Tutorial',
}
);
export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
constructor(
private readonly initializerContext: PluginInitializerContext<ConfigSchema>
) {
this.initializerContext = initializerContext;
}
public setup(core: CoreSetup, plugins: ApmPluginSetupDeps) {
const config = this.initializerContext.config.get();
const pluginSetupDeps = plugins;
@ -369,6 +377,7 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
path: '/storage-explorer',
searchable: featureFlags.storageExplorerAvailable,
},
{ id: 'tutorial', title: apmTutorialTitle, path: '/tutorial' },
],
async mount(appMountParameters: AppMountParameters<unknown>) {
@ -399,6 +408,7 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
locator,
};
}
public start(core: CoreStart, plugins: ApmPluginStartDeps) {
const { fleet } = plugins;
if (fleet) {

View file

@ -18,7 +18,7 @@ export function MobileAddData() {
aria-label={i18n.translate('xpack.exploratoryView.page_header.addMobileDataLink.label', {
defaultMessage: 'Navigate to a tutorial about adding mobile APM data',
})}
href={kibana.services?.application?.getUrlForApp('/home#/tutorial/apm')}
href={kibana.services?.application?.getUrlForApp('/apm/tutorial')}
color="primary"
iconType="indexOpen"
>

View file

@ -18,7 +18,7 @@ export function UXAddData() {
aria-label={i18n.translate('xpack.exploratoryView.page_header.addUXDataLink.label', {
defaultMessage: 'Navigate to a tutorial about adding user experience APM data',
})}
href={kibana.services?.application?.getUrlForApp('/home#/tutorial/apm')}
href={kibana.services?.application?.getUrlForApp('/apm/tutorial')}
color="primary"
iconType="indexOpen"
>

View file

@ -44,7 +44,7 @@ export const useGetAgentIncomingData = (
}
if (installedPolicy?.name === 'apm') {
href = getAbsolutePath('/app/home#/tutorial/apm');
href = getAbsolutePath('/app/apm/tutorial');
text = i18n.translate('xpack.fleet.confirmIncomingData.installApmAgentButtonText', {
defaultMessage: 'Install APM Agent',
});

View file

@ -58,7 +58,7 @@ export const getContent = (
addTitle: i18n.translate('xpack.observability.statusVisualization.apm.link', {
defaultMessage: 'Add data',
}),
addLink: http.basePath.prepend('/app/home#/tutorial/apm'),
addLink: http.basePath.prepend('/app/apm/tutorial'),
learnMoreLink: docLinks.links.apm.overview,
goToAppTitle: i18n.translate('xpack.observability.statusVisualization.apm.goToAppTitle', {
defaultMessage: 'Show services inventory',
@ -116,7 +116,7 @@ export const getContent = (
addTitle: i18n.translate('xpack.observability.statusVisualization.ux.link', {
defaultMessage: 'Add data',
}),
addLink: http.basePath.prepend('/app/home#/tutorial/apm'),
addLink: http.basePath.prepend('/app/apm/tutorial'),
learnMoreLink: docLinks.links.observability.userExperience,
goToAppTitle: i18n.translate('xpack.observability.statusVisualization.ux.goToAppTitle', {
defaultMessage: 'Show dashboard',

View file

@ -35,7 +35,7 @@ const testBoxes = [
description:
'Get deeper visibility into your applications with extensive support for popular languages, OpenTelemetry, and distributed tracing.',
addTitle: 'Add data',
addLink: '/app/home#/tutorial/apm',
addLink: '/app/apm/tutorial',
learnMoreLink: 'http://lean-more-link-example.com',
goToAppTitle: 'Show services inventory',
goToAppLink: '/app/apm/services',
@ -75,7 +75,7 @@ const testBoxes = [
description:
'Collect, measure, and analyze performance data that reflects real-world user experiences.',
addTitle: 'Add data',
addLink: '/app/home#/tutorial/apm',
addLink: '/app/apm/tutorial',
learnMoreLink: 'http://lean-more-link-example.com',
goToAppTitle: 'Show dashboard',
goToAppLink: '/app/ux',

View file

@ -87,7 +87,7 @@ const getEmptySections = ({ http }: { http: HttpSetup }): Section[] => {
linkTitle: i18n.translate('xpack.observability.emptySection.apps.apm.link', {
defaultMessage: 'Install Agent',
}),
href: http.basePath.prepend('/app/home#/tutorial/apm'),
href: http.basePath.prepend('/app/apm/tutorial'),
},
{
id: 'infra_metrics',
@ -130,7 +130,7 @@ const getEmptySections = ({ http }: { http: HttpSetup }): Section[] => {
linkTitle: i18n.translate('xpack.observability.emptySection.apps.ux.link', {
defaultMessage: 'Install RUM Agent',
}),
href: http.basePath.prepend('/app/home#/tutorial/apm'),
href: http.basePath.prepend('/app/apm/tutorial'),
},
{
id: 'alert',

View file

@ -25,6 +25,7 @@ import { euiDarkVars, euiLightVars } from '@kbn/ui-theme';
import React from 'react';
import ReactDOM from 'react-dom';
import { RouteComponentProps, RouteProps } from 'react-router-dom';
import { ConfigSchema } from '..';
import { customLogsRoutes } from '../components/app/custom_logs/wizard';
import { ObservabilityOnboardingHeaderActionMenu } from '../components/app/header_action_menu';
import {
@ -121,11 +122,13 @@ export function ObservabilityOnboardingAppRoot({
core,
deps,
corePlugins: { observability, data },
config,
}: {
appMountParameters: AppMountParameters;
core: CoreStart;
deps: ObservabilityOnboardingPluginSetupDeps;
corePlugins: ObservabilityOnboardingPluginStartDeps;
config: ConfigSchema;
}) {
const { history, setHeaderActionMenu, theme$ } = appMountParameters;
const i18nCore = core.i18n;
@ -142,6 +145,7 @@ export function ObservabilityOnboardingAppRoot({
...plugins,
observability,
data,
config,
}}
>
<KibanaThemeProvider
@ -181,11 +185,13 @@ export const renderApp = ({
deps,
appMountParameters,
corePlugins,
config,
}: {
core: CoreStart;
deps: ObservabilityOnboardingPluginSetupDeps;
appMountParameters: AppMountParameters;
corePlugins: ObservabilityOnboardingPluginStartDeps;
config: ConfigSchema;
}) => {
const { element } = appMountParameters;
@ -195,6 +201,7 @@ export const renderApp = ({
core={core}
deps={deps}
corePlugins={corePlugins}
config={config}
/>,
element
);

View file

@ -61,7 +61,7 @@ export function Home() {
navigateToKibanaUrl('/app/observabilityOnboarding/customLogs');
};
const handleClickApmSetupGuide = () => {
navigateToKibanaUrl('/app/home#/tutorial/apm');
navigateToKibanaUrl('/app/apm/tutorial');
};
const handleClickKubernetesSetupGuide = () => {
navigateToKibanaUrl('/app/integrations/detail/kubernetes');

View file

@ -6,12 +6,7 @@
*/
import { useKibana } from '@kbn/kibana-react-plugin/public';
import type { ApplicationStart, HttpStart } from '@kbn/core/public';
interface ObservabilityOnboardingAppServices {
application: ApplicationStart;
http: HttpStart;
}
import { ObservabilityOnboardingAppServices } from '..';
export function useKibanaNavigation() {
const {

View file

@ -5,17 +5,38 @@
* 2.0.
*/
import { PluginInitializer, PluginInitializerContext } from '@kbn/core/public';
import {
ApplicationStart,
HttpStart,
PluginInitializer,
PluginInitializerContext,
} from '@kbn/core/public';
import {
ObservabilityOnboardingPlugin,
ObservabilityOnboardingPluginSetup,
ObservabilityOnboardingPluginStart,
} from './plugin';
export interface ConfigSchema {
ui: {
enabled: boolean;
};
serverless: {
enabled: boolean;
};
}
export interface ObservabilityOnboardingAppServices {
application: ApplicationStart;
http: HttpStart;
config: ConfigSchema;
}
export const plugin: PluginInitializer<
ObservabilityOnboardingPluginSetup,
ObservabilityOnboardingPluginStart
> = (ctx: PluginInitializerContext) => new ObservabilityOnboardingPlugin(ctx);
> = (ctx: PluginInitializerContext<ConfigSchema>) =>
new ObservabilityOnboardingPlugin(ctx);
export type {
ObservabilityOnboardingPluginSetup,

View file

@ -52,10 +52,11 @@ export class ObservabilityOnboardingPlugin
core: CoreSetup,
plugins: ObservabilityOnboardingPluginSetupDeps
) {
const config = this.ctx.config.get<ObservabilityOnboardingConfig>();
const {
ui: { enabled: isObservabilityOnboardingUiEnabled },
serverless: { enabled: isServerlessEnabled },
} = this.ctx.config.get<ObservabilityOnboardingConfig>();
} = config;
const pluginSetupDeps = plugins;
@ -90,6 +91,7 @@ export class ObservabilityOnboardingPlugin
deps: pluginSetupDeps,
appMountParameters,
corePlugins: corePlugins as ObservabilityOnboardingPluginStartDeps,
config,
});
},
});

View file

@ -78,7 +78,7 @@ export function UXActionMenu({
color="primary"
iconType="indexOpen"
iconSide="left"
href={application.getUrlForApp('/home#/tutorial/apm')}
href={application.getUrlForApp('/apm/tutorial')}
>
{i18n.translate('xpack.ux.addDataButtonLabel', {
defaultMessage: 'Add data',

View file

@ -48,7 +48,7 @@ export function RumHome() {
'Enable RUM with the APM agent to collect user experience data.',
}
),
href: http.basePath.prepend(`/app/home#/tutorial/apm`),
href: http.basePath.prepend('/app/apm/tutorial'),
},
},
docsLink: docLinks.links.observability.guide,