From bafc89e0922ac0084ecca6aed16cd807969f2833 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Fri, 30 Oct 2020 09:28:14 -0500 Subject: [PATCH] Service overview tab and route (#81972) (#82046) Placeholder tab and route for service overview page. Fixes #81718. --- .../app/Main/route_config/index.tsx | 14 + .../app/ServiceDetails/ServiceDetailTabs.tsx | 16 +- .../components/app/service_overview/index.tsx | 246 ++++++++++++++++++ .../service_overview.test.tsx | 29 +++ .../Links/apm/service_overview_link.tsx | 23 ++ 5 files changed, 324 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/apm/public/components/app/service_overview/index.tsx create mode 100644 x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx create mode 100644 x-pack/plugins/apm/public/components/shared/Links/apm/service_overview_link.tsx diff --git a/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx b/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx index 0d61ca8e39845..f96dc14e34264 100644 --- a/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx @@ -92,6 +92,12 @@ function ServiceDetailsNodes( return ; } +function ServiceDetailsOverview( + props: RouteComponentProps<{ serviceName: string }> +) { + return ; +} + function ServiceDetailsServiceMap( props: RouteComponentProps<{ serviceName: string }> ) { @@ -215,6 +221,14 @@ export const routes: APMRouteDefinition[] = [ `/services/${props.match.params.serviceName}/transactions` )(props), } as APMRouteDefinition<{ serviceName: string }>, + { + exact: true, + path: '/services/:serviceName/overview', + breadcrumb: i18n.translate('xpack.apm.breadcrumb.overviewTitle', { + defaultMessage: 'Overview', + }), + component: ServiceDetailsOverview, + } as APMRouteDefinition<{ serviceName: string }>, // errors { exact: true, diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx index 76c8a289b830c..d51e4a2dd3d7c 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx @@ -16,16 +16,24 @@ import { ErrorOverviewLink } from '../../shared/Links/apm/ErrorOverviewLink'; import { MetricOverviewLink } from '../../shared/Links/apm/MetricOverviewLink'; import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; import { ServiceNodeOverviewLink } from '../../shared/Links/apm/ServiceNodeOverviewLink'; +import { ServiceOverviewLink } from '../../shared/Links/apm/service_overview_link'; import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink'; import { ErrorGroupOverview } from '../ErrorGroupOverview'; import { ServiceMap } from '../ServiceMap'; import { ServiceMetrics } from '../ServiceMetrics'; import { ServiceNodeOverview } from '../ServiceNodeOverview'; +import { ServiceOverview } from '../service_overview'; import { TransactionOverview } from '../TransactionOverview'; interface Props { serviceName: string; - tab: 'transactions' | 'errors' | 'metrics' | 'nodes' | 'service-map'; + tab: + | 'errors' + | 'metrics' + | 'nodes' + | 'overview' + | 'service-map' + | 'transactions'; } export function ServiceDetailTabs({ serviceName, tab }: Props) { @@ -34,13 +42,13 @@ export function ServiceDetailTabs({ serviceName, tab }: Props) { const overviewTab = { link: ( - + {i18n.translate('xpack.apm.serviceDetails.overviewTabLabel', { defaultMessage: 'Overview', })} - + ), - render: () => <>, + render: () => , name: 'overview', }; diff --git a/x-pack/plugins/apm/public/components/app/service_overview/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx new file mode 100644 index 0000000000000..81f23b6427508 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx @@ -0,0 +1,246 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import styled from 'styled-components'; +import { useTrackPageview } from '../../../../../observability/public'; +import { ErrorOverviewLink } from '../../shared/Links/apm/ErrorOverviewLink'; +import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; +import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink'; + +const rowHeight = 310; +const latencyChartRowHeight = 230; + +const Row = styled(EuiFlexItem)` + height: ${rowHeight}px; +`; + +const LatencyChartRow = styled(EuiFlexItem)` + height: ${latencyChartRowHeight}px; +`; + +const TableLinkFlexItem = styled(EuiFlexItem)` + & > a { + text-align: right; + } +`; + +interface ServiceOverviewProps { + serviceName: string; +} + +export function ServiceOverview({ serviceName }: ServiceOverviewProps) { + useTrackPageview({ app: 'apm', path: 'service_overview' }); + useTrackPageview({ app: 'apm', path: 'service_overview', delay: 15000 }); + + return ( + + + + + Search bar + + + Comparison picker + + + Date picker + + + + + + +

+ {i18n.translate('xpack.apm.serviceOverview.latencyChartTitle', { + defaultMessage: 'Latency', + })} +

+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.trafficChartTitle', + { + defaultMessage: 'Traffic', + } + )} +

+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.transactionsTableTitle', + { + defaultMessage: 'Transactions', + } + )} +

+
+
+ + + {i18n.translate( + 'xpack.apm.serviceOverview.transactionsTableLinkText', + { + defaultMessage: 'View transactions', + } + )} + + +
+
+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.errorRateChartTitle', + { + defaultMessage: 'Error rate', + } + )} +

+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.errorsTableTitle', + { + defaultMessage: 'Errors', + } + )} +

+
+
+ + + {i18n.translate( + 'xpack.apm.serviceOverview.errorsTableLinkText', + { + defaultMessage: 'View errors', + } + )} + + +
+
+
+
+
+ + + + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.averageDurationBySpanTypeChartTitle', + { + defaultMessage: 'Average duration by span type', + } + )} +

+
+
+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.dependenciesTableTitle', + { + defaultMessage: 'Dependencies', + } + )} +

+
+
+ + + {i18n.translate( + 'xpack.apm.serviceOverview.dependenciesTableLinkText', + { + defaultMessage: 'View service map', + } + )} + + +
+
+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.instancesLatencyDistributionChartTitle', + { + defaultMessage: 'Instances latency distribution', + } + )} +

+
+
+
+ + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.instancesTableTitle', + { + defaultMessage: 'Instances', + } + )} +

+
+
+
+
+
+
+ ); +} diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx new file mode 100644 index 0000000000000..4e2063930a9c9 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx @@ -0,0 +1,29 @@ +/* + * 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 React, { ReactNode } from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { MockApmPluginContextWrapper } from '../../../context/ApmPluginContext/MockApmPluginContext'; +import { ServiceOverview } from './'; + +function Wrapper({ children }: { children?: ReactNode }) { + return ( + + {children} + + ); +} + +describe('ServiceOverview', () => { + it('renders', () => { + expect(() => + render(, { + wrapper: Wrapper, + }) + ).not.toThrowError(); + }); +}); diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/service_overview_link.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/service_overview_link.tsx new file mode 100644 index 0000000000000..5d7859e7362c7 --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/service_overview_link.tsx @@ -0,0 +1,23 @@ +/* + * 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. + */ +/* + * 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 React from 'react'; +import { APMLink, APMLinkExtendProps } from './APMLink'; + +interface ServiceOverviewLinkProps extends APMLinkExtendProps { + serviceName: string; +} + +export function ServiceOverviewLink({ + serviceName, + ...rest +}: ServiceOverviewLinkProps) { + return ; +}