Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions x-pack/plugins/observability_solution/apm/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"ml",
"security",
"spaces",
"serverless",
"taskManager",
"usageCollection",
"customIntegrations", // Move this to requiredPlugins after completely migrating from the Tutorials Home App
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@ import { useBreadcrumb } from '../../../context/breadcrumbs/use_breadcrumb';
export const Breadcrumb = ({
title,
href,
omitOnServerless = false,
children,
}: {
title: string;
href: string;
omitOnServerless?: boolean;
children: React.ReactElement;
}) => {
const { core } = useApmPluginContext();

useBreadcrumb(
() => ({ title, href: core.http.basePath.prepend('/app/apm' + href) }),
[core.http.basePath, href, title]
[core.http.basePath, href, title],
{
omitOnServerless,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Side nav items are automatically added, so we have to avoid adding repeated items to the breadcrumbs

image

}
);

return children;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ export function DependencyDetailView({ children }: { children: React.ReactChild
rangeTo,
refreshInterval,
refreshPaused,
]
],
{
omitRootOnServerless: true,
}
);
return <DependencyDetailTemplate>{children}</DependencyDetailTemplate>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ export function DependencyOperationDetailView() {
},
} = useApmParams('/dependencies/operation');

useDependencyDetailOperationsBreadcrumb();
useDependencyDetailOperationsBreadcrumb({
title: spanName,
href: router.link('/dependencies/operation', {
query,
}),
});

const { start, end } = useTimeRange({ rangeFrom, rangeTo });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function TraceOverview({ children }: { children: React.ReactElement }) {
: [];

return (
<Breadcrumb href="/traces" title={title}>
<Breadcrumb href="/traces" title={title} omitOnServerless>
<ApmMainTemplate
pageTitle={title}
pageSectionProps={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const apmRoutes = {
defaultMessage: 'APM',
})}
href="/"
omitOnServerless
>
<Outlet />
</Breadcrumb>
Expand All @@ -95,7 +96,7 @@ const apmRoutes = {
// this route fails on navigation unless it's defined before home
'/service-groups': {
element: (
<Breadcrumb title={ServiceGroupsTitle} href={'/service-groups'}>
<Breadcrumb title={ServiceGroupsTitle} href={'/service-groups'} omitOnServerless>
<ApmMainTemplate
pageTitle={ServiceGroupsTitle}
environmentFilter={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { euiDarkVars, euiLightVars } from '@kbn/ui-theme';
import React from 'react';
import { DefaultTheme, ThemeProvider } from 'styled-components';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { useKibanaEnvironmentContextProvider } from '../../../context/kibana_environment_context/use_kibana_environment_context';
import { KibanaEnvironmentContextProvider } from '../../../context/kibana_environment_context/kibana_environment_context';
import { AnomalyDetectionJobsContextProvider } from '../../../context/anomaly_detection_jobs/anomaly_detection_jobs_context';
import {
ApmPluginContext,
Expand Down Expand Up @@ -56,7 +56,6 @@ export function ApmAppRoot({
apmServices: ApmServices;
}) {
const { appMountParameters, kibanaEnvironment, core } = apmPluginContextValue;
const KibanaEnvironmentContextProvider = useKibanaEnvironmentContextProvider(kibanaEnvironment);
const { history } = appMountParameters;
const i18nCore = core.i18n;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values';
import { environmentRt } from '../../../../common/environment_rt';
import { TraceSearchType } from '../../../../common/trace_explorer';
import { ApmTimeRangeMetadataContextProvider } from '../../../context/time_range_metadata/time_range_metadata_context';
import { Breadcrumb } from '../../app/breadcrumb';
import { ServiceInventory } from '../../app/service_inventory';
import { ServiceMapHome } from '../../app/service_map';
import { TopTracesOverview } from '../../app/top_traces_overview';
Expand Down Expand Up @@ -50,11 +49,13 @@ function serviceGroupPage<TPath extends string>({
return {
[path]: {
element: (
<Breadcrumb title={title} href={path}>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

was removed to avoid conflicts with useBreadcrumb in ServiceGroupTemplate

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

totally off topic: never knew about these alert indicators. I'll immediately start (ab)-using these! :)

Other type of alerts per my recent findings:

Note

Highlights information that users should take into account, even when skimming.

Tip

Optional information to help a user be more successful.

Important

Crucial information necessary for users to succeed.

Warning

Critical content demanding immediate user attention due to potential risks.

Caution

Negative potential consequences of an action.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to say that I found that out a couple of days ago in one of @tonyghiani's PRs. 😄

<ServiceGroupTemplate pageTitle={title} serviceGroupContextTab={serviceGroupContextTab}>
{element}
</ServiceGroupTemplate>
</Breadcrumb>
<ServiceGroupTemplate
pageTitle={title}
pagePath={path}
serviceGroupContextTab={serviceGroupContextTab}
>
{element}
</ServiceGroupTemplate>
),
params: t.type({
query: t.type({ serviceGroup: t.string }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function page<
return {
[path]: {
element: (
<Breadcrumb title={title} href={path}>
<Breadcrumb title={title} href={path} omitOnServerless>
<ApmMainTemplate
pageTitle={title}
showServiceGroupSaveButton={showServiceGroupSaveButton}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ export function ApmServiceWrapper() {
}),
},
],
[query, router, serviceName]
[query, router, serviceName],
{
omitRootOnServerless: true,
}
);

return <Outlet />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const settingsRoute = {
title={i18n.translate('xpack.apm.views.listSettings.title', {
defaultMessage: 'Settings',
})}
omitOnServerless
>
<Outlet />
</Breadcrumb>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ function TemplateWithContext({ title, children, selectedTabKey, searchBarOptions
]
: []),
],
[query, router, selectedTab, serviceName, servicesLink]
[query, router, selectedTab, serviceName, servicesLink],
{
omitRootOnServerless: true,
}
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ function TemplateWithContext({ title, children, selectedTabKey, searchBarOptions
]
: []),
],
[query, router, selectedTab, serviceName, servicesLink]
[query, router, selectedTab, serviceName, servicesLink],
{
omitRootOnServerless: true,
}
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ import { useEntityManagerEnablementContext } from '../../../context/entity_manag
export function ServiceGroupTemplate({
pageTitle,
pageHeader,
pagePath,
children,
environmentFilter = true,
serviceGroupContextTab,
...pageTemplateProps
}: {
pageTitle?: React.ReactNode;
pageTitle: string;
pageHeader?: EuiPageHeaderProps;
pagePath: string;
children: React.ReactNode;
environmentFilter?: boolean;
serviceGroupContextTab: ServiceGroupContextTab['key'];
Expand Down Expand Up @@ -81,34 +83,44 @@ export function ServiceGroupTemplate({
);

const tabs = useTabs(serviceGroupContextTab);
const selectedTab = tabs?.find(({ isSelected }) => isSelected);
const selectedTab = tabs.find(({ isSelected }) => isSelected);

// this is only used for building the breadcrumbs for the service group page
useBreadcrumb(
() => [
{
title: i18n.translate('xpack.apm.serviceGroups.breadcrumb.title', {
defaultMessage: 'Services',
}),
href: serviceGroupsLink,
},
...(selectedTab
() =>
!serviceGroupName
? [
...(serviceGroupName
{
title: pageTitle,
href: pagePath,
},
]
: [
{
title: i18n.translate('xpack.apm.serviceGroups.breadcrumb.title', {
defaultMessage: 'Services',
}),
href: serviceGroupsLink,
},
{
title: serviceGroupName,
href: router.link('/services', { query }),
},
...(selectedTab
? [
{
title: serviceGroupName,
href: router.link('/services', { query }),
},
title: selectedTab.breadcrumbLabel || selectedTab.label,
href: selectedTab.href,
} as { title: string; href: string },
]
: []),
{
title: selectedTab.breadcrumbLabel || selectedTab.label,
href: selectedTab.href,
} as { title: string; href: string },
]
: []),
],
[query, router, selectedTab, serviceGroupName, serviceGroupsLink]
],
[pagePath, pageTitle, query, router, selectedTab, serviceGroupName, serviceGroupsLink],
{
omitRootOnServerless: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Services is automatically added on serverless

}
);

return (
<ApmMainTemplate
pageTitle={serviceGroupsPageTitle}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ChromeBreadcrumb } from '@kbn/core/public';
import { compact, isEqual } from 'lodash';
import React, { createContext, useMemo, useState } from 'react';
import { useBreadcrumbs } from '@kbn/observability-shared-plugin/public';
import { useKibana } from '../kibana_context/use_kibana';

export interface Breadcrumb {
title: string;
Expand All @@ -25,6 +26,9 @@ export const BreadcrumbsContext = createContext<BreadcrumbApi | undefined>(undef

export function BreadcrumbsContextProvider({ children }: { children: React.ReactElement }) {
const [, forceUpdate] = useState({});
const {
services: { serverless },
} = useKibana();

const breadcrumbs = useMemo(() => {
return new Map<Route, Breadcrumb[]>();
Expand Down Expand Up @@ -72,7 +76,7 @@ export function BreadcrumbsContextProvider({ children }: { children: React.React
};
});

useBreadcrumbs(formattedBreadcrumbs);
useBreadcrumbs(formattedBreadcrumbs, { serverless });

return <BreadcrumbsContext.Provider value={api}>{children}</BreadcrumbsContext.Provider>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,16 @@ import { useCurrentRoute } from '@kbn/typed-react-router-config';
import { useContext, useEffect, useRef } from 'react';
import { castArray } from 'lodash';
import { Breadcrumb, BreadcrumbsContext } from './context';
import { useKibanaEnvironmentContext } from '../kibana_environment_context/use_kibana_environment_context';

export function useBreadcrumb(
callback: () => Breadcrumb | Breadcrumb[],
fnDeps: any[],
options?: { omitRootOnServerless?: boolean; omitOnServerless?: boolean }
) {
const { isServerlessEnv } = useKibanaEnvironmentContext();
const { omitRootOnServerless = false, omitOnServerless = false } = options || {};

export function useBreadcrumb(callback: () => Breadcrumb | Breadcrumb[], fnDeps: any[]) {
const api = useContext(BreadcrumbsContext);

if (!api) {
Expand All @@ -22,14 +30,25 @@ export function useBreadcrumb(callback: () => Breadcrumb | Breadcrumb[], fnDeps:
const matchedRoute = useRef(match?.route);

useEffect(() => {
if (isServerlessEnv && omitOnServerless) {
return;
}

if (matchedRoute.current && matchedRoute.current !== match?.route) {
api.unset(matchedRoute.current);
}

matchedRoute.current = match?.route;

if (matchedRoute.current) {
api.set(matchedRoute.current, castArray(callback()));
const breadcrumbs = castArray(callback());

api.set(
matchedRoute.current,
isServerlessEnv && omitRootOnServerless && breadcrumbs.length >= 1
? breadcrumbs.slice(1)
: breadcrumbs
);
}

return () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { createContext } from 'react';

export interface KibanaEnvContext {
Expand All @@ -14,3 +14,17 @@ export interface KibanaEnvContext {
}

export const KibanaEnvironmentContext = createContext<KibanaEnvContext>({});

export function KibanaEnvironmentContextProvider({
children,
kibanaEnvironment,
}: {
kibanaEnvironment: KibanaEnvContext;
children: React.ReactElement;
}) {
return (
<KibanaEnvironmentContext.Provider value={kibanaEnvironment}>
{children}
</KibanaEnvironmentContext.Provider>
);
}
Loading