[APM] Refactoring service and transaction links (#86986)

* refactoring service and transaction links

* refactoring links

* addressing PR comments

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Cauê Marcondes 2021-01-07 13:00:39 +01:00 committed by GitHub
parent f59711945d
commit 2d564ddf19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 215 additions and 114 deletions

View file

@ -13,7 +13,7 @@ import {
import { Transaction } from '../../../../../../../typings/es_schemas/ui/transaction';
import { TransactionDetailLink } from '../../../../../shared/Links/apm/TransactionDetailLink';
import { StickyProperties } from '../../../../../shared/StickyProperties';
import { ServiceOrTransactionsOverviewLink } from '../../../../../shared/Links/apm/service_transactions_overview';
import { ServiceOrTransactionsOverviewLink } from '../../../../../shared/Links/apm/service_transactions_overview_link';
interface Props {
transaction?: Transaction;

View file

@ -15,7 +15,7 @@ import {
import { NOT_AVAILABLE_LABEL } from '../../../../../../../../common/i18n';
import { Span } from '../../../../../../../../typings/es_schemas/ui/span';
import { StickyProperties } from '../../../../../../shared/StickyProperties';
import { ServiceOrTransactionsOverviewLink } from '../../../../../../shared/Links/apm/service_transactions_overview';
import { ServiceOrTransactionsOverviewLink } from '../../../../../../shared/Links/apm/service_transactions_overview_link';
import { TransactionDetailLink } from '../../../../../../shared/Links/apm/TransactionDetailLink';
interface Props {

View file

@ -10,20 +10,20 @@ import React, { ReactNode } from 'react';
import { isJavaAgentName, isRumAgentName } from '../../../../common/agent_name';
import { enableServiceOverview } from '../../../../common/ui_settings_keys';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context';
import { useErrorOverviewHref } from '../../shared/Links/apm/ErrorOverviewLink';
import { useMetricOverviewHref } from '../../shared/Links/apm/MetricOverviewLink';
import { useServiceMapHref } from '../../shared/Links/apm/ServiceMapLink';
import { useServiceNodeOverviewHref } from '../../shared/Links/apm/ServiceNodeOverviewLink';
import { useServiceOverviewHref } from '../../shared/Links/apm/service_overview_link';
import { useServiceOrTransactionsOverviewHref } from '../../shared/Links/apm/service_transactions_overview';
import { useTransactionsOverviewHref } from '../../shared/Links/apm/transaction_overview_link';
import { MainTabs } from '../../shared/main_tabs';
import { ErrorGroupOverview } from '../ErrorGroupOverview';
import { ServiceMap } from '../ServiceMap';
import { ServiceMetrics } from '../service_metrics';
import { ServiceNodeOverview } from '../ServiceNodeOverview';
import { ServiceMetrics } from '../service_metrics';
import { ServiceOverview } from '../service_overview';
import { TransactionOverview } from '../transaction_overview';
import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context';
interface Tab {
key: string;
@ -60,7 +60,7 @@ export function ServiceDetailTabs({ serviceName, tab }: Props) {
const transactionsTab = {
key: 'transactions',
href: useServiceOrTransactionsOverviewHref(serviceName),
href: useTransactionsOverviewHref(serviceName),
text: i18n.translate('xpack.apm.serviceDetails.transactionsTabLabel', {
defaultMessage: 'Transactions',
}),

View file

@ -27,7 +27,7 @@ import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
import { fontSizes, px, truncate, unit } from '../../../../style/variables';
import { ManagedTable, ITableColumn } from '../../../shared/ManagedTable';
import { EnvironmentBadge } from '../../../shared/EnvironmentBadge';
import { ServiceOrTransactionsOverviewLink } from '../../../shared/Links/apm/service_transactions_overview';
import { ServiceOrTransactionsOverviewLink } from '../../../shared/Links/apm/service_transactions_overview_link';
import { AgentIcon } from '../../../shared/AgentIcon';
import { HealthBadge } from './HealthBadge';
import { ServiceListMetric } from './ServiceListMetric';

View file

@ -32,7 +32,7 @@ import { px, unit } from '../../../../style/variables';
import { SparkPlot } from '../../../shared/charts/spark_plot';
import { ImpactBar } from '../../../shared/ImpactBar';
import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink';
import { TransactionOverviewLink } from '../../../shared/Links/apm/transaction_overview_ink';
import { TransactionOverviewLink } from '../../../shared/Links/apm/transaction_overview_link';
import { TableFetchWrapper } from '../../../shared/table_fetch_wrapper';
import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip';
import { ServiceOverviewTableContainer } from '../service_overview_table_container';

View file

@ -3,11 +3,10 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiLink } from '@elastic/eui';
import React from 'react';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { APMQueryParams } from '../url_helpers';
import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink';
import { APMLinkExtendProps, useAPMHref } from './APMLink';
const persistedFilters: Array<keyof APMQueryParams> = [
'host',
@ -25,13 +24,6 @@ interface Props extends APMLinkExtendProps {
}
export function MetricOverviewLink({ serviceName, ...rest }: Props) {
const { urlParams } = useUrlParams();
return (
<APMLink
path={`/services/${serviceName}/metrics`}
query={pickKeys(urlParams as APMQueryParams, ...persistedFilters)}
{...rest}
/>
);
const href = useMetricOverviewHref(serviceName);
return <EuiLink href={href} {...rest} />;
}

View file

@ -3,15 +3,15 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiLink } from '@elastic/eui';
import React from 'react';
import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink';
function pathFor(serviceName?: string) {
return serviceName ? `/services/${serviceName}/service-map` : '/service-map';
}
import { APMLinkExtendProps, useAPMHref } from './APMLink';
export function useServiceMapHref(serviceName?: string) {
return useAPMHref(pathFor(serviceName));
const pathFor = serviceName
? `/services/${serviceName}/service-map`
: '/service-map';
return useAPMHref(pathFor);
}
interface ServiceMapLinkProps extends APMLinkExtendProps {
@ -19,6 +19,6 @@ interface ServiceMapLinkProps extends APMLinkExtendProps {
}
export function ServiceMapLink({ serviceName, ...rest }: ServiceMapLinkProps) {
const path = pathFor(serviceName);
return <APMLink path={path} {...rest} />;
const href = useServiceMapHref(serviceName);
return <EuiLink href={href} {...rest} />;
}

View file

@ -3,11 +3,8 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { APMQueryParams } from '../url_helpers';
import { useAPMHref } from './APMLink';
const persistedFilters: Array<keyof APMQueryParams> = [
'host',
@ -19,19 +16,3 @@ const persistedFilters: Array<keyof APMQueryParams> = [
export function useServiceNodeOverviewHref(serviceName: string) {
return useAPMHref(`/services/${serviceName}/nodes`, persistedFilters);
}
interface Props extends APMLinkExtendProps {
serviceName: string;
}
export function ServiceNodeOverviewLink({ serviceName, ...rest }: Props) {
const { urlParams } = useUrlParams();
return (
<APMLink
path={`/services/${serviceName}/nodes`}
query={pickKeys(urlParams as APMQueryParams, ...persistedFilters)}
{...rest}
/>
);
}

View file

@ -9,11 +9,8 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { APMQueryParams } from '../url_helpers';
import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink';
import { useAPMHref } from './APMLink';
const persistedFilters: Array<keyof APMQueryParams> = [
'transactionResult',
@ -25,15 +22,3 @@ const persistedFilters: Array<keyof APMQueryParams> = [
export function useTraceOverviewHref() {
return useAPMHref('/traces', persistedFilters);
}
export function TraceOverviewLink(props: APMLinkExtendProps) {
const { urlParams } = useUrlParams();
return (
<APMLink
path="/traces"
query={pickKeys(urlParams as APMQueryParams, ...persistedFilters)}
{...props}
/>
);
}

View file

@ -9,22 +9,11 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { APMQueryParams } from '../url_helpers';
import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink';
import { useAPMHref } from './APMLink';
const persistedFilters: Array<keyof APMQueryParams> = ['host', 'agentName'];
export function useServiceInventoryHref() {
return useAPMHref('/services', persistedFilters);
}
export function ServiceInventoryLink(props: APMLinkExtendProps) {
const { urlParams } = useUrlParams();
const query = pickKeys(urlParams as APMQueryParams, ...persistedFilters);
return <APMLink path="/services" query={query} {...props} />;
}

View file

@ -8,11 +8,10 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiLink } from '@elastic/eui';
import React from 'react';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { APMQueryParams } from '../url_helpers';
import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink';
import { APMLinkExtendProps, useAPMHref } from './APMLink';
interface ServiceOverviewLinkProps extends APMLinkExtendProps {
serviceName: string;
@ -30,13 +29,6 @@ export function ServiceOverviewLink({
serviceName,
...rest
}: ServiceOverviewLinkProps) {
const { urlParams } = useUrlParams();
return (
<APMLink
path={`/services/${serviceName}/overview`}
query={pickKeys(urlParams as APMQueryParams, ...persistedFilters)}
{...rest}
/>
);
const href = useServiceOverviewHref(serviceName);
return <EuiLink href={href} {...rest} />;
}

View file

@ -0,0 +1,87 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { render } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { createMemoryHistory } from 'history';
import React from 'react';
import { Router } from 'react-router-dom';
import { MockApmPluginContextWrapper } from '../../../../context/apm_plugin/mock_apm_plugin_context';
import { MockUrlParamsContextProvider } from '../../../../context/url_params_context/mock_url_params_context_provider';
import {
ServiceOrTransactionsOverviewLink,
useServiceOrTransactionsOverviewHref,
} from './service_transactions_overview_link';
const history = createMemoryHistory();
function wrapper({ queryParams }: { queryParams?: Record<string, unknown> }) {
return ({ children }: { children: React.ReactElement }) => (
<MockApmPluginContextWrapper>
<Router history={history}>
<MockUrlParamsContextProvider params={queryParams}>
{children}
</MockUrlParamsContextProvider>
</Router>
</MockApmPluginContextWrapper>
);
}
describe('Service or transactions overview link', () => {
describe('useServiceOrTransactionsOverviewHref', () => {
it('returns service link', () => {
const { result } = renderHook(
() => useServiceOrTransactionsOverviewHref('foo'),
{ wrapper: wrapper({}) }
);
expect(result.current).toEqual('/basepath/app/apm/services/foo');
});
it('returns service link with persisted query items', () => {
const { result } = renderHook(
() => useServiceOrTransactionsOverviewHref('foo'),
{ wrapper: wrapper({ queryParams: { latencyAggregationType: 'avg' } }) }
);
expect(result.current).toEqual(
'/basepath/app/apm/services/foo?latencyAggregationType=avg'
);
});
});
describe('ServiceOrTransactionsOverviewLink', () => {
function getHref(container: HTMLElement) {
return ((container as HTMLDivElement).children[0] as HTMLAnchorElement)
.href;
}
it('returns service link', () => {
const Component = wrapper({});
const { container } = render(
<Component>
<ServiceOrTransactionsOverviewLink serviceName="foo">
Service name
</ServiceOrTransactionsOverviewLink>
</Component>
);
expect(getHref(container)).toEqual(
'http://localhost/basepath/app/apm/services/foo'
);
});
it('returns service link with persisted query items', () => {
const Component = wrapper({
queryParams: { latencyAggregationType: 'avg' },
});
const { container } = render(
<Component>
<ServiceOrTransactionsOverviewLink serviceName="foo">
Service name
</ServiceOrTransactionsOverviewLink>
</Component>
);
expect(getHref(container)).toEqual(
'http://localhost/basepath/app/apm/services/foo?latencyAggregationType=avg'
);
});
});
});

View file

@ -3,11 +3,10 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiLink } from '@elastic/eui';
import React from 'react';
import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { APMQueryParams } from '../url_helpers';
import { APMLinkExtendProps, useAPMHref } from './APMLink';
const persistedFilters: Array<keyof APMQueryParams> = [
'transactionResult',
@ -19,7 +18,7 @@ const persistedFilters: Array<keyof APMQueryParams> = [
];
export function useServiceOrTransactionsOverviewHref(serviceName: string) {
return useAPMHref(`/services/${serviceName}/transactions`, persistedFilters);
return useAPMHref(`/services/${serviceName}`, persistedFilters);
}
interface Props extends APMLinkExtendProps {
@ -30,13 +29,6 @@ export function ServiceOrTransactionsOverviewLink({
serviceName,
...rest
}: Props) {
const { urlParams } = useUrlParams();
return (
<APMLink
path={`/services/${serviceName}`}
query={pickKeys(urlParams as APMQueryParams, ...persistedFilters)}
{...rest}
/>
);
const href = useServiceOrTransactionsOverviewHref(serviceName);
return <EuiLink href={href} {...rest} />;
}

View file

@ -0,0 +1,87 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { render } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { createMemoryHistory } from 'history';
import React from 'react';
import { Router } from 'react-router-dom';
import { MockApmPluginContextWrapper } from '../../../../context/apm_plugin/mock_apm_plugin_context';
import { MockUrlParamsContextProvider } from '../../../../context/url_params_context/mock_url_params_context_provider';
import {
TransactionOverviewLink,
useTransactionsOverviewHref,
} from './transaction_overview_link';
const history = createMemoryHistory();
function wrapper({ queryParams }: { queryParams?: Record<string, unknown> }) {
return ({ children }: { children: React.ReactElement }) => (
<MockApmPluginContextWrapper>
<Router history={history}>
<MockUrlParamsContextProvider params={queryParams}>
{children}
</MockUrlParamsContextProvider>
</Router>
</MockApmPluginContextWrapper>
);
}
describe('Transactions overview link', () => {
describe('useTransactionsOverviewHref', () => {
it('returns transaction link', () => {
const { result } = renderHook(() => useTransactionsOverviewHref('foo'), {
wrapper: wrapper({}),
});
expect(result.current).toEqual(
'/basepath/app/apm/services/foo/transactions'
);
});
it('returns transaction link with persisted query items', () => {
const { result } = renderHook(() => useTransactionsOverviewHref('foo'), {
wrapper: wrapper({ queryParams: { latencyAggregationType: 'avg' } }),
});
expect(result.current).toEqual(
'/basepath/app/apm/services/foo/transactions?latencyAggregationType=avg'
);
});
});
describe('TransactionOverviewLink', () => {
function getHref(container: HTMLElement) {
return ((container as HTMLDivElement).children[0] as HTMLAnchorElement)
.href;
}
it('returns transaction link', () => {
const Component = wrapper({});
const { container } = render(
<Component>
<TransactionOverviewLink serviceName="foo">
Service name
</TransactionOverviewLink>
</Component>
);
expect(getHref(container)).toEqual(
'http://localhost/basepath/app/apm/services/foo/transactions'
);
});
it('returns transaction link with persisted query items', () => {
const Component = wrapper({
queryParams: { latencyAggregationType: 'avg' },
});
const { container } = render(
<Component>
<TransactionOverviewLink serviceName="foo">
Service name
</TransactionOverviewLink>
</Component>
);
expect(getHref(container)).toEqual(
'http://localhost/basepath/app/apm/services/foo/transactions?latencyAggregationType=avg'
);
});
});
});

View file

@ -4,11 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiLink } from '@elastic/eui';
import React from 'react';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { APMLink, APMLinkExtendProps } from './APMLink';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { APMQueryParams } from '../url_helpers';
import { APMLinkExtendProps, useAPMHref } from './APMLink';
interface Props extends APMLinkExtendProps {
serviceName: string;
@ -18,14 +17,11 @@ const persistedFilters: Array<keyof APMQueryParams> = [
'latencyAggregationType',
];
export function TransactionOverviewLink({ serviceName, ...rest }: Props) {
const { urlParams } = useUrlParams();
return (
<APMLink
path={`/services/${serviceName}/transactions/`}
query={pickKeys(urlParams as APMQueryParams, ...persistedFilters)}
{...rest}
/>
);
export function useTransactionsOverviewHref(serviceName: string) {
return useAPMHref(`/services/${serviceName}/transactions`, persistedFilters);
}
export function TransactionOverviewLink({ serviceName, ...rest }: Props) {
const href = useTransactionsOverviewHref(serviceName);
return <EuiLink href={href} {...rest} />;
}