[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/exhaustive-deps': [
'error',
{ additionalHooks: '^(useFetcher|useProgressiveFetcher)$' },
{ additionalHooks: '^(useFetcher|useProgressiveFetcher|useBreadcrumb)$' },
],
},
},

View file

@ -18,7 +18,10 @@ export const Breadcrumb = ({
children: React.ReactElement;
}) => {
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;
};

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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