[APM] Breadcrumbs not updating from service jump on service map (#136144)

* invalidating useEffect to update breadcrumbs

* removing useEffect

* removing callback function

* adding callback

* adding usEffect

* fixing

* adding fnDeps param

* addressing pr comments

* addressing pr comments
This commit is contained in:
Cauê Marcondes 2022-07-19 15:57:38 -04:00 committed by GitHub
parent 8c844d8b49
commit bca30a8e6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 227 additions and 154 deletions

View file

@ -979,7 +979,7 @@ module.exports = {
'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
'react-hooks/exhaustive-deps': [ 'react-hooks/exhaustive-deps': [
'error', 'error',
{ additionalHooks: '^(useFetcher|useProgressiveFetcher)$' }, { additionalHooks: '^(useFetcher|useProgressiveFetcher|useBreadcrumb)$' },
], ],
}, },
}, },

View file

@ -18,7 +18,10 @@ export const Breadcrumb = ({
children: React.ReactElement; children: React.ReactElement;
}) => { }) => {
const { core } = useApmPluginContext(); const { core } = useApmPluginContext();
useBreadcrumb({ title, href: core.http.basePath.prepend('/app/apm' + href) }); useBreadcrumb(
() => ({ title, href: core.http.basePath.prepend('/app/apm' + href) }),
[core.http.basePath, href, title]
);
return children; return children;
}; };

View file

@ -30,26 +30,39 @@ export function DependencyDetailOverview() {
const apmRouter = useApmRouter(); const apmRouter = useApmRouter();
useBreadcrumb([ useBreadcrumb(
{ () => [
title: i18n.translate( {
'xpack.apm.dependencyDetailOverview.breadcrumbTitle', title: i18n.translate(
{ defaultMessage: 'Overview' } 'xpack.apm.dependencyDetailOverview.breadcrumbTitle',
), { defaultMessage: 'Overview' }
href: apmRouter.link('/dependencies/overview', { ),
query: { href: apmRouter.link('/dependencies/overview', {
dependencyName, query: {
rangeFrom, dependencyName,
rangeTo, rangeFrom,
refreshInterval, rangeTo,
refreshPaused, refreshInterval,
environment, refreshPaused,
kuery, environment,
comparisonEnabled, kuery,
}, comparisonEnabled,
}), },
}, }),
]); },
],
[
apmRouter,
comparisonEnabled,
dependencyName,
environment,
kuery,
rangeFrom,
rangeTo,
refreshInterval,
refreshPaused,
]
);
return ( return (
<> <>

View file

@ -31,36 +31,49 @@ export function DependencyDetailView({
const apmRouter = useApmRouter(); const apmRouter = useApmRouter();
useBreadcrumb([ useBreadcrumb(
{ () => [
title: DependenciesInventoryTitle, {
href: apmRouter.link('/dependencies/inventory', { title: DependenciesInventoryTitle,
query: { href: apmRouter.link('/dependencies/inventory', {
rangeFrom, query: {
rangeTo, rangeFrom,
refreshInterval, rangeTo,
refreshPaused, refreshInterval,
environment, refreshPaused,
kuery, environment,
comparisonEnabled, kuery,
}, comparisonEnabled,
}), },
}, }),
{ },
title: dependencyName, {
href: apmRouter.link('/dependencies', { title: dependencyName,
query: { href: apmRouter.link('/dependencies', {
dependencyName, query: {
rangeFrom, dependencyName,
rangeTo, rangeFrom,
refreshInterval, rangeTo,
refreshPaused, refreshInterval,
environment, refreshPaused,
kuery, environment,
comparisonEnabled, kuery,
}, comparisonEnabled,
}), },
}, }),
]); },
],
[
apmRouter,
comparisonEnabled,
dependencyName,
environment,
kuery,
rangeFrom,
rangeTo,
refreshInterval,
refreshPaused,
]
);
return <DependencyDetailTemplate>{children}</DependencyDetailTemplate>; return <DependencyDetailTemplate>{children}</DependencyDetailTemplate>;
} }

View file

@ -127,23 +127,36 @@ export function ErrorGroupDetails() {
const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const { start, end } = useTimeRange({ rangeFrom, rangeTo });
useBreadcrumb({ useBreadcrumb(
title: groupId, () => ({
href: apmRouter.link('/services/{serviceName}/errors/{groupId}', { title: groupId,
path: { href: apmRouter.link('/services/{serviceName}/errors/{groupId}', {
serviceName, path: {
groupId, serviceName,
}, groupId,
query: { },
rangeFrom, query: {
rangeTo, rangeFrom,
environment, rangeTo,
kuery, environment,
serviceGroup, kuery,
comparisonEnabled, serviceGroup,
}, comparisonEnabled,
},
}),
}), }),
}); [
apmRouter,
comparisonEnabled,
environment,
groupId,
kuery,
rangeFrom,
rangeTo,
serviceGroup,
serviceName,
]
);
const { data: errorGroupData } = useFetcher( const { data: errorGroupData } = useFetcher(
(callApmApi) => { (callApmApi) => {

View file

@ -60,19 +60,22 @@ export function ServiceNodeMetrics() {
const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const { start, end } = useTimeRange({ rangeFrom, rangeTo });
useBreadcrumb({ useBreadcrumb(
title: getServiceNodeName(serviceNodeName), () => ({
href: apmRouter.link( title: getServiceNodeName(serviceNodeName),
'/services/{serviceName}/nodes/{serviceNodeName}/metrics', href: apmRouter.link(
{ '/services/{serviceName}/nodes/{serviceNodeName}/metrics',
path: { {
serviceName, path: {
serviceNodeName, serviceName,
}, serviceNodeName,
query, },
} query,
), }
}); ),
}),
[apmRouter, query, serviceName, serviceNodeName]
);
const { data } = useServiceMetricChartsFetcher({ const { data } = useServiceMetricChartsFetcher({
serviceNodeName, serviceNodeName,

View file

@ -44,13 +44,16 @@ export function TransactionDetails() {
replace(history, { query: { transactionType } }); replace(history, { query: { transactionType } });
} }
useBreadcrumb({ useBreadcrumb(
title: transactionName, () => ({
href: apmRouter.link('/services/{serviceName}/transactions/view', { title: transactionName,
path, href: apmRouter.link('/services/{serviceName}/transactions/view', {
query, path,
query,
}),
}), }),
}); [apmRouter, path, query, transactionName]
);
const isServerless = isServerlessAgent(runtimeName); const isServerless = isServerlessAgent(runtimeName);

View file

@ -19,19 +19,22 @@ export function ApmServiceWrapper() {
const router = useApmRouter(); const router = useApmRouter();
useBreadcrumb([ useBreadcrumb(
{ () => [
title: ServiceInventoryTitle, {
href: router.link('/services', { query }), title: ServiceInventoryTitle,
}, href: router.link('/services', { query }),
{ },
title: serviceName, {
href: router.link('/services/{serviceName}', { title: serviceName,
query, href: router.link('/services/{serviceName}', {
path: { serviceName }, query,
}), path: { serviceName },
}, }),
]); },
],
[query, router, serviceName]
);
return <Outlet />; return <Outlet />;
} }

View file

@ -86,13 +86,16 @@ function TemplateWithContext({
const tabs = useTabs({ selectedTab }); const tabs = useTabs({ selectedTab });
useBreadcrumb({ useBreadcrumb(
title, () => ({
href: router.link(`/services/{serviceName}/${selectedTab}` as const, { title,
path: { serviceName }, href: router.link(`/services/{serviceName}/${selectedTab}` as const, {
query, path: { serviceName },
query,
}),
}), }),
}); [query, router, selectedTab, serviceName, title]
);
return ( return (
<ApmMainTemplate <ApmMainTemplate

View file

@ -116,30 +116,33 @@ export function ServiceGroupTemplate({
const tabs = useTabs(serviceGroupContextTab); const tabs = useTabs(serviceGroupContextTab);
const selectedTab = tabs?.find(({ isSelected }) => isSelected); const selectedTab = tabs?.find(({ isSelected }) => isSelected);
useBreadcrumb([ useBreadcrumb(
{ () => [
title: i18n.translate('xpack.apm.serviceGroups.breadcrumb.title', { {
defaultMessage: 'Services', title: i18n.translate('xpack.apm.serviceGroups.breadcrumb.title', {
}), defaultMessage: 'Services',
href: serviceGroupsLink, }),
}, href: serviceGroupsLink,
...(selectedTab },
? [ ...(selectedTab
...(serviceGroupName ? [
? [ ...(serviceGroupName
{ ? [
title: serviceGroupName, {
href: router.link('/services', { query }), title: serviceGroupName,
}, href: router.link('/services', { query }),
] },
: []), ]
{ : []),
title: selectedTab.label, {
href: selectedTab.href, title: selectedTab.label,
} as { title: string; href: string }, href: selectedTab.href,
] } as { title: string; href: string },
: []), ]
]); : []),
],
[query, router, selectedTab, serviceGroupName, serviceGroupsLink]
);
return ( return (
<ApmMainTemplate <ApmMainTemplate
pageTitle={isServiceGroupsEnabled ? serviceGroupsPageTitle : pageTitle} pageTitle={isServiceGroupsEnabled ? serviceGroupsPageTitle : pageTitle}

View file

@ -10,7 +10,10 @@ import { useContext, useEffect, useRef } from 'react';
import { castArray } from 'lodash'; import { castArray } from 'lodash';
import { Breadcrumb, BreadcrumbsContext } from './context'; import { Breadcrumb, BreadcrumbsContext } from './context';
export function useBreadcrumb(breadcrumb: Breadcrumb | Breadcrumb[]) { export function useBreadcrumb(
callback: () => Breadcrumb | Breadcrumb[],
fnDeps: any[]
) {
const api = useContext(BreadcrumbsContext); const api = useContext(BreadcrumbsContext);
if (!api) { if (!api) {
@ -29,7 +32,7 @@ export function useBreadcrumb(breadcrumb: Breadcrumb | Breadcrumb[]) {
matchedRoute.current = match?.route; matchedRoute.current = match?.route;
if (matchedRoute.current) { if (matchedRoute.current) {
api.set(matchedRoute.current, castArray(breadcrumb)); api.set(matchedRoute.current, castArray(callback()));
} }
return () => { return () => {
@ -38,5 +41,5 @@ export function useBreadcrumb(breadcrumb: Breadcrumb | Breadcrumb[]) {
} }
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, [match, ...fnDeps]);
} }

View file

@ -26,24 +26,37 @@ export function useDependencyDetailOperationsBreadcrumb() {
const apmRouter = useApmRouter(); const apmRouter = useApmRouter();
useBreadcrumb([ useBreadcrumb(
{ () => [
title: i18n.translate( {
'xpack.apm.dependencyDetailOperations.breadcrumbTitle', title: i18n.translate(
{ defaultMessage: 'Operations' } 'xpack.apm.dependencyDetailOperations.breadcrumbTitle',
), { defaultMessage: 'Operations' }
href: apmRouter.link('/dependencies/operations', { ),
query: { href: apmRouter.link('/dependencies/operations', {
dependencyName, query: {
rangeFrom, dependencyName,
rangeTo, rangeFrom,
refreshInterval, rangeTo,
refreshPaused, refreshInterval,
environment, refreshPaused,
kuery, environment,
comparisonEnabled, kuery,
}, comparisonEnabled,
}), },
}, }),
]); },
],
[
apmRouter,
comparisonEnabled,
dependencyName,
environment,
kuery,
rangeFrom,
rangeTo,
refreshInterval,
refreshPaused,
]
);
} }