From 1d4549d879026f0397edf645c9fc37f066272c5e Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Fri, 6 Nov 2020 08:11:01 -0600 Subject: [PATCH 1/5] APM header changes - Make APM and UX headers size medium instead of large - Remove margin around APM main container - Make APM tabs condensed - Switch environment filter and date picker positions - Move search bar (kuery + date picker) below the tabs - Wrap pages in `EuiPage` components - Set a minimum width on the enironment selector so it doesn't collapse when loading - Don't show search bar on service map Fixes #81954. --- .../plugins/apm/public/application/index.tsx | 2 - .../components/app/Correlations/index.tsx | 2 +- .../app/ErrorGroupDetails/index.tsx | 108 +++--- .../app/ErrorGroupOverview/index.tsx | 66 ++-- .../apm/public/components/app/Home/index.tsx | 20 +- .../components/app/RumDashboard/RumHome.tsx | 2 +- .../app/ServiceDetails/ServiceDetailTabs.tsx | 15 +- .../components/app/ServiceDetails/index.tsx | 2 +- .../app/ServiceMap/cytoscape_options.ts | 1 - .../components/app/ServiceMap/index.tsx | 49 ++- .../components/app/ServiceMetrics/index.tsx | 44 ++- .../app/ServiceNodeMetrics/index.tsx | 2 +- .../app/ServiceNodeOverview/index.tsx | 67 ++-- .../components/app/TraceOverview/index.tsx | 39 +- .../app/TransactionDetails/index.tsx | 97 ++--- .../app/TransactionOverview/index.tsx | 156 ++++---- .../app/service_inventory/index.tsx | 71 ++-- .../components/app/service_overview/index.tsx | 347 +++++++++--------- .../shared/ApmHeader/apm_header.stories.tsx | 2 +- .../components/shared/ApmHeader/index.tsx | 35 +- .../shared/EnvironmentFilter/index.tsx | 6 + .../public/components/shared/EuiTabLink.tsx | 49 --- .../components/shared/KueryBar/index.tsx | 10 +- .../public/components/shared/main_tabs.tsx | 26 ++ .../public/components/shared/search_bar.tsx | 29 ++ .../public/components/app/header/index.tsx | 2 +- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 28 files changed, 646 insertions(+), 605 deletions(-) delete mode 100644 x-pack/plugins/apm/public/components/shared/EuiTabLink.tsx create mode 100644 x-pack/plugins/apm/public/components/shared/main_tabs.tsx create mode 100644 x-pack/plugins/apm/public/components/shared/search_bar.tsx diff --git a/x-pack/plugins/apm/public/application/index.tsx b/x-pack/plugins/apm/public/application/index.tsx index 4e3217ce17ed1..66ff09ad89b9b 100644 --- a/x-pack/plugins/apm/public/application/index.tsx +++ b/x-pack/plugins/apm/public/application/index.tsx @@ -30,11 +30,9 @@ import { ApmPluginSetupDeps } from '../plugin'; import { createCallApmApi } from '../services/rest/createCallApmApi'; import { createStaticIndexPattern } from '../services/rest/index_pattern'; import { setHelpExtension } from '../setHelpExtension'; -import { px, units } from '../style/variables'; import { setReadonlyBadge } from '../updateBadge'; const MainContainer = styled.div` - padding: ${px(units.plus)}; height: 100%; `; diff --git a/x-pack/plugins/apm/public/components/app/Correlations/index.tsx b/x-pack/plugins/apm/public/components/app/Correlations/index.tsx index afee2b9f5e881..e3dea70a232eb 100644 --- a/x-pack/plugins/apm/public/components/app/Correlations/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Correlations/index.tsx @@ -75,7 +75,7 @@ export function Correlations() { return ( <> - +

Correlations

diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/index.tsx index e95d35142684d..f47674ba5891f 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/index.tsx @@ -8,6 +8,8 @@ import { EuiBadge, EuiFlexGroup, EuiFlexItem, + EuiPage, + EuiPageBody, EuiPanel, EuiSpacer, EuiText, @@ -24,6 +26,7 @@ import { useUrlParams } from '../../../hooks/useUrlParams'; import { callApmApi } from '../../../services/rest/createCallApmApi'; import { fontFamilyCode, fontSizes, px, units } from '../../../style/variables'; import { ApmHeader } from '../../shared/ApmHeader'; +import { SearchBar } from '../../shared/search_bar'; import { DetailView } from './DetailView'; import { ErrorDistribution } from './Distribution'; @@ -120,7 +123,7 @@ export function ErrorGroupDetails({ location, match }: ErrorGroupDetailsProps) { errorGroupData.error?.error.exception?.[0].handled === false; return ( -
+ <> @@ -146,62 +149,67 @@ export function ErrorGroupDetails({ location, match }: ErrorGroupDetailsProps) { )} - - - - - {showDetails && ( - - - {logMessage && ( - + + + + + {showDetails && ( + + + {logMessage && ( + + + {logMessage} + + )} - {logMessage} - + {excMessage || NOT_AVAILABLE_LABEL} + + {culprit || NOT_AVAILABLE_LABEL} + + + )} + - {i18n.translate( - 'xpack.apm.errorGroupDetails.exceptionMessageLabel', - { - defaultMessage: 'Exception message', - } - )} - - {excMessage || NOT_AVAILABLE_LABEL} - - {culprit || NOT_AVAILABLE_LABEL} - - - )} - + + + {showDetails && ( + )} - /> - - - {showDetails && ( - - )} -
+ + + ); } diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/index.tsx index 42b0016ca8cfe..52fb4b33cbc55 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/index.tsx @@ -7,6 +7,7 @@ import { EuiFlexGroup, EuiFlexItem, + EuiPage, EuiPanel, EuiSpacer, EuiTitle, @@ -19,6 +20,7 @@ import { useFetcher } from '../../../hooks/useFetcher'; import { useUrlParams } from '../../../hooks/useUrlParams'; import { callApmApi } from '../../../services/rest/createCallApmApi'; import { LocalUIFilters } from '../../shared/LocalUIFilters'; +import { SearchBar } from '../../shared/search_bar'; import { ErrorDistribution } from '../ErrorGroupDetails/Distribution'; import { ErrorGroupList } from './List'; @@ -95,39 +97,41 @@ function ErrorGroupOverview({ serviceName }: ErrorGroupOverviewProps) { return ( <> - - - - - - - - - - - - - - -

Errors

-
+ + + + + + + + + + + - -
-
-
+ + +

Errors

+
+ + + +
+ + + ); } diff --git a/x-pack/plugins/apm/public/components/app/Home/index.tsx b/x-pack/plugins/apm/public/components/app/Home/index.tsx index c4224bf676abb..594288b708665 100644 --- a/x-pack/plugins/apm/public/components/app/Home/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Home/index.tsx @@ -8,7 +8,8 @@ import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, - EuiTabs, + EuiPage, + EuiTab, EuiTitle, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -17,13 +18,14 @@ import { $ElementType } from 'utility-types'; import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; import { getAlertingCapabilities } from '../../alerting/get_alert_capabilities'; import { ApmHeader } from '../../shared/ApmHeader'; -import { EuiTabLink } from '../../shared/EuiTabLink'; import { AnomalyDetectionSetupLink } from '../../shared/Links/apm/AnomalyDetectionSetupLink'; import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; import { ServiceInventoryLink } from '../../shared/Links/apm/service_inventory_link'; import { SettingsLink } from '../../shared/Links/apm/SettingsLink'; import { TraceOverviewLink } from '../../shared/Links/apm/TraceOverviewLink'; import { SetupInstructionsLink } from '../../shared/Links/SetupInstructionsLink'; +import { MainTabs } from '../../shared/main_tabs'; +import { SearchBar } from '../../shared/search_bar'; import { ServiceMap } from '../ServiceMap'; import { ServiceInventory } from '../service_inventory'; import { TraceOverview } from '../TraceOverview'; @@ -101,11 +103,11 @@ export function Home({ tab }: Props) { } = getAlertingCapabilities(plugins, core.application.capabilities); return ( -
+ <> - +

APM

@@ -135,14 +137,14 @@ export function Home({ tab }: Props) {
- + {homeTabs.map((homeTab) => ( - + {homeTab.link} - + ))} - + {selectedTab.render()} -
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/RumHome.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/RumHome.tsx index f25761bd8abad..da83d3425a99c 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/RumHome.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/RumHome.tsx @@ -21,7 +21,7 @@ export function RumHome() { - +

{UX_LABEL}

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 625a8e73debc9..2351bdebfba3a 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx @@ -4,20 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiTabs } from '@elastic/eui'; +import { EuiTab } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { isJavaAgentName, isRumAgentName } from '../../../../common/agent_name'; import { enableServiceOverview } from '../../../../common/ui_settings_keys'; import { useAgentName } from '../../../hooks/useAgentName'; import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; -import { EuiTabLink } from '../../shared/EuiTabLink'; 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 { MainTabs } from '../../shared/main_tabs'; import { ErrorGroupOverview } from '../ErrorGroupOverview'; import { ServiceMap } from '../ServiceMap'; import { ServiceMetrics } from '../ServiceMetrics'; @@ -132,16 +132,13 @@ export function ServiceDetailTabs({ serviceName, tab }: Props) { return ( <> - + {tabs.map((serviceTab) => ( - + {serviceTab.link} - + ))} - + {selectedTab ? selectedTab.render() : null} ); diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/index.tsx index 8825702cafd51..b4cea026815ea 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/index.tsx @@ -43,7 +43,7 @@ export function ServiceDetails({ match, tab }: Props) { - +

{serviceName}

diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/cytoscape_options.ts b/x-pack/plugins/apm/public/components/app/ServiceMap/cytoscape_options.ts index e51f53567b5ff..d8a8a3c8e9ab4 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/cytoscape_options.ts +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/cytoscape_options.ts @@ -252,7 +252,6 @@ center, ${theme.eui.euiColorLightShade}`, backgroundSize: `${theme.eui.euiSizeL} ${theme.eui.euiSizeL}`, cursor: `${status === FETCH_STATUS.LOADING ? 'wait' : 'grab'}`, - margin: `-${theme.eui.gutterTypes.gutterLarge}`, marginTop: 0, }); diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx index 752f9b7fda243..d5a9b2a0c917a 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx @@ -6,6 +6,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; import React, { ReactNode } from 'react'; +import styled from 'styled-components'; import { useTrackPageview } from '../../../../../observability/public'; import { invalidLicenseMessage, @@ -17,20 +18,27 @@ import { useLicense } from '../../../hooks/useLicense'; import { useTheme } from '../../../hooks/useTheme'; import { useUrlParams } from '../../../hooks/useUrlParams'; import { callApmApi } from '../../../services/rest/createCallApmApi'; +import { DatePicker } from '../../shared/DatePicker'; import { LicensePrompt } from '../../shared/LicensePrompt'; import { Controls } from './Controls'; import { Cytoscape } from './Cytoscape'; import { getCytoscapeDivStyle } from './cytoscape_options'; import { EmptyBanner } from './EmptyBanner'; import { EmptyPrompt } from './empty_prompt'; -import { TimeoutPrompt } from './timeout_prompt'; import { Popover } from './Popover'; +import { TimeoutPrompt } from './timeout_prompt'; import { useRefDimensions } from './useRefDimensions'; interface ServiceMapProps { serviceName?: string; } +const ServiceMapDatePickerFlexGroup = styled(EuiFlexGroup)` + padding: ${({ theme }) => theme.eui.euiSizeM}; + border-bottom: ${({ theme }) => theme.eui.euiBorderThin}; + margin: 0; +`; + function PromptContainer({ children }: { children: ReactNode }) { return ( - - - {serviceName && } - {status === FETCH_STATUS.LOADING && } - - - + <> + + + + + +
+ + + {serviceName && } + {status === FETCH_STATUS.LOADING && } + + +
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/ServiceMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceMetrics/index.tsx index 042752ef62f53..5808c54d578c6 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMetrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMetrics/index.tsx @@ -7,6 +7,7 @@ import { EuiFlexGrid, EuiFlexItem, + EuiPage, EuiPanel, EuiSpacer, EuiFlexGroup, @@ -18,6 +19,7 @@ import { useUrlParams } from '../../../hooks/useUrlParams'; import { LegacyChartsSyncContextProvider as ChartsSyncContextProvider } from '../../../context/charts_sync_context'; import { Projection } from '../../../../common/projections'; import { LocalUIFilters } from '../../shared/LocalUIFilters'; +import { SearchBar } from '../../shared/search_bar'; interface ServiceMetricsProps { agentName: string; @@ -46,26 +48,28 @@ export function ServiceMetrics({ return ( <> - - - - - - - - - {data.charts.map((chart) => ( - - - - - - ))} - - - - - + + + + + + + + + + {data.charts.map((chart) => ( + + + + + + ))} + + + + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/ServiceNodeMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceNodeMetrics/index.tsx index 566585c67e212..7c6b63f75382c 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceNodeMetrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceNodeMetrics/index.tsx @@ -83,7 +83,7 @@ export function ServiceNodeMetrics({ match }: ServiceNodeMetricsProps) { - +

{serviceName}

diff --git a/x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx index 02dc3934dd01e..b05785db14625 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx @@ -3,30 +3,31 @@ * 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, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, + EuiPage, EuiPanel, EuiToolTip, - EuiSpacer, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import React, { useMemo } from 'react'; import styled from 'styled-components'; +import { UNIDENTIFIED_SERVICE_NODES_LABEL } from '../../../../common/i18n'; +import { Projection } from '../../../../common/projections'; +import { SERVICE_NODE_NAME_MISSING } from '../../../../common/service_nodes'; import { asDynamicBytes, asInteger, asPercent, } from '../../../../common/utils/formatters'; -import { UNIDENTIFIED_SERVICE_NODES_LABEL } from '../../../../common/i18n'; -import { SERVICE_NODE_NAME_MISSING } from '../../../../common/service_nodes'; -import { Projection } from '../../../../common/projections'; -import { LocalUIFilters } from '../../shared/LocalUIFilters'; -import { useUrlParams } from '../../../hooks/useUrlParams'; -import { ManagedTable, ITableColumn } from '../../shared/ManagedTable'; import { useFetcher } from '../../../hooks/useFetcher'; +import { useUrlParams } from '../../../hooks/useUrlParams'; +import { px, truncate, unit } from '../../../style/variables'; import { ServiceNodeMetricOverviewLink } from '../../shared/Links/apm/ServiceNodeMetricOverviewLink'; -import { truncate, px, unit } from '../../../style/variables'; +import { LocalUIFilters } from '../../shared/LocalUIFilters'; +import { ITableColumn, ManagedTable } from '../../shared/ManagedTable'; +import { SearchBar } from '../../shared/search_bar'; const INITIAL_PAGE_SIZE = 25; const INITIAL_SORT_FIELD = 'cpu'; @@ -157,29 +158,31 @@ function ServiceNodeOverview({ serviceName }: ServiceNodeOverviewProps) { return ( <> - - - - - - - - - - - + + + + + + + + + + + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/TraceOverview/index.tsx b/x-pack/plugins/apm/public/components/app/TraceOverview/index.tsx index 06b4459fb56eb..797ec5e17ab3c 100644 --- a/x-pack/plugins/apm/public/components/app/TraceOverview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TraceOverview/index.tsx @@ -4,7 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import { + EuiPanel, + EuiFlexGroup, + EuiFlexItem, + EuiPage, + EuiSpacer, +} from '@elastic/eui'; import React, { useMemo } from 'react'; import { FETCH_STATUS, useFetcher } from '../../../hooks/useFetcher'; import { TraceList } from './TraceList'; @@ -13,6 +19,7 @@ import { useTrackPageview } from '../../../../../observability/public'; import { LocalUIFilters } from '../../shared/LocalUIFilters'; import { Projection } from '../../../../common/projections'; import { APIReturnType } from '../../../services/rest/createCallApmApi'; +import { SearchBar } from '../../shared/search_bar'; type TracesAPIResponse = APIReturnType<'/api/apm/traces'>; const DEFAULT_RESPONSE: TracesAPIResponse = { @@ -56,20 +63,22 @@ export function TraceOverview() { return ( <> - - - - - - - - - - - + + + + + + + + + + + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/index.tsx index efdd7b1f34221..a0bac350be367 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/index.tsx @@ -8,6 +8,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, + EuiPage, EuiPanel, EuiSpacer, EuiTitle, @@ -32,6 +33,7 @@ import { useUrlParams } from '../../../hooks/useUrlParams'; import { LocalUIFilters } from '../../shared/LocalUIFilters'; import { HeightRetainer } from '../../shared/HeightRetainer'; import { Correlations } from '../Correlations'; +import { SearchBar } from '../../shared/search_bar'; interface Sample { traceId: string; @@ -105,57 +107,58 @@ export function TransactionDetails({ }; return ( -
+ <> - +

{transactionName}

- + - - - - - - - - - - - - - - { - if (!isEmpty(bucket.samples)) { - selectSampleFromBucketClick(bucket.samples[0]); - } - }} - /> - - - - - - - - - -
+ + + + + + + + + + + + + + { + if (!isEmpty(bucket.samples)) { + selectSampleFromBucketClick(bucket.samples[0]); + } + }} + /> + + + + + + + + + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionOverview/index.tsx index 5444d2d521f37..23b2461e00877 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/index.tsx @@ -10,6 +10,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, + EuiPage, EuiPanel, EuiSpacer, EuiTitle, @@ -22,6 +23,7 @@ import React, { useMemo } from 'react'; import { useLocation } from 'react-router-dom'; import { useTrackPageview } from '../../../../../observability/public'; import { Projection } from '../../../../common/projections'; +import { TRANSACTION_PAGE_LOAD } from '../../../../common/transaction_types'; import { LegacyChartsSyncContextProvider as ChartsSyncContextProvider } from '../../../context/charts_sync_context'; import { IUrlParams } from '../../../context/UrlParamsContext/types'; import { useServiceTransactionTypes } from '../../../hooks/useServiceTransactionTypes'; @@ -33,11 +35,11 @@ import { ElasticDocsLink } from '../../shared/Links/ElasticDocsLink'; import { fromQuery, toQuery } from '../../shared/Links/url_helpers'; import { LocalUIFilters } from '../../shared/LocalUIFilters'; import { TransactionTypeFilter } from '../../shared/LocalUIFilters/TransactionTypeFilter'; +import { SearchBar } from '../../shared/search_bar'; +import { Correlations } from '../Correlations'; import { TransactionList } from './TransactionList'; import { useRedirect } from './useRedirect'; -import { TRANSACTION_PAGE_LOAD } from '../../../../common/transaction_types'; import { UserExperienceCallout } from './user_experience_callout'; -import { Correlations } from '../Correlations'; function getRedirectLocation({ urlParams, @@ -118,83 +120,87 @@ export function TransactionOverview({ serviceName }: TransactionOverviewProps) { return ( <> + - - - - - - - - - - - {transactionType === TRANSACTION_PAGE_LOAD && ( - <> - - - - )} - - - - - + + + + + + + + + + + {transactionType === TRANSACTION_PAGE_LOAD && ( + <> + + + + )} + + + - - -

Transactions

-
- {!transactionListData.isAggregationAccurate && ( - -

- - xpack.apm.ui.transactionGroupBucketSize - - ), - }} - /> - - {i18n.translate( - 'xpack.apm.transactionCardinalityWarning.docsLink', - { defaultMessage: 'Learn more in the docs' } - )} - -

-
- )} - - -
-
-
+ + +

Transactions

+
+ + {!transactionListData.isAggregationAccurate && ( + +

+ + xpack.apm.ui.transactionGroupBucketSize + + ), + }} + /> + + + {i18n.translate( + 'xpack.apm.transactionCardinalityWarning.docsLink', + { defaultMessage: 'Learn more in the docs' } + )} + +

+
+ )} + + +
+
+
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx index 43af1a3e04dcd..61e78200a5316 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx @@ -4,8 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import { EuiLink } from '@elastic/eui'; +import { + EuiPanel, + EuiFlexGroup, + EuiFlexItem, + EuiLink, + EuiPage, + EuiSpacer, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useMemo } from 'react'; import url from 'url'; @@ -22,6 +28,7 @@ import { MLCallout } from './ServiceList/MLCallout'; import { useLocalStorage } from '../../../hooks/useLocalStorage'; import { useAnomalyDetectionJobs } from '../../../hooks/useAnomalyDetectionJobs'; import { Correlations } from '../Correlations'; +import { SearchBar } from '../../shared/search_bar'; const initialData = { items: [], @@ -121,37 +128,39 @@ export function ServiceInventory() { return ( <> - - - - - - - - - - - {displayMlCallout ? ( + + + + + + + + + + {displayMlCallout ? ( + + setUserHasDismissedCallout(true)} + /> + + ) : null} - setUserHasDismissedCallout(true)} /> + + + } + /> + - ) : null} - - - - } - /> - - - - - + + + + ); } 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 index 342152b572f1e..0e8df0325b660 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx @@ -4,7 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiPage, + EuiPanel, + EuiTitle, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import styled from 'styled-components'; @@ -15,6 +21,7 @@ import { ErroneousTransactionsRateChart } from '../../shared/charts/erroneous_tr import { ErrorOverviewLink } from '../../shared/Links/apm/ErrorOverviewLink'; import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink'; +import { SearchBar } from '../../shared/search_bar'; const rowHeight = 310; const latencyChartRowHeight = 230; @@ -47,212 +54,202 @@ export function ServiceOverview({ 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', - } - )} - - -
-
-
-
-
- - - {!isRumAgentName(agentName) && ( + + + + + + +

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

+
+
+
+ +

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

-
- )} - - - - - -

+ + + + + +

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

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

-
-
- - - {i18n.translate( - 'xpack.apm.serviceOverview.errorsTableLinkText', - { - defaultMessage: 'View errors', - } - )} - - -
-
-
-
-
- - - - - - + + + + + + + + + + {!isRumAgentName(agentName) && ( + +

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

-
-
- - - - - - - -

+ + + + )} + + + + + +

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

+
+
+ + {i18n.translate( - 'xpack.apm.serviceOverview.dependenciesTableTitle', + 'xpack.apm.serviceOverview.errorsTableLinkText', { - defaultMessage: 'Dependencies', + 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.dependenciesTableLinkText', + 'xpack.apm.serviceOverview.instancesLatencyDistributionChartTitle', { - defaultMessage: 'View service map', + defaultMessage: 'Instances latency distribution', } )} - - - - - - - - - - - - -

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

-
-
-
- - - -

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

-
-
-
-
-
- +

+
+
+
+ + + +

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

+
+
+
+
+
+
+
); } diff --git a/x-pack/plugins/apm/public/components/shared/ApmHeader/apm_header.stories.tsx b/x-pack/plugins/apm/public/components/shared/ApmHeader/apm_header.stories.tsx index 4078998bc7e3e..56501d8c916f4 100644 --- a/x-pack/plugins/apm/public/components/shared/ApmHeader/apm_header.stories.tsx +++ b/x-pack/plugins/apm/public/components/shared/ApmHeader/apm_header.stories.tsx @@ -38,7 +38,7 @@ export default { export function Example() { return ( - +

GET /api/v1/regions/azure-eastus2/clusters/elasticsearch/xc18de071deb4262be54baebf5f6a1ce/proxy/_snapshot/found-snapshots/_all diff --git a/x-pack/plugins/apm/public/components/shared/ApmHeader/index.tsx b/x-pack/plugins/apm/public/components/shared/ApmHeader/index.tsx index 6674abe9b8ce5..7e09dcb5cb69f 100644 --- a/x-pack/plugins/apm/public/components/shared/ApmHeader/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/ApmHeader/index.tsx @@ -4,32 +4,23 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { ReactNode } from 'react'; -import { DatePicker } from '../DatePicker'; +import styled from 'styled-components'; import { EnvironmentFilter } from '../EnvironmentFilter'; -import { KueryBar } from '../KueryBar'; + +const HeaderFlexGroup = styled(EuiFlexGroup)` + padding: ${({ theme }) => theme.eui.gutterTypes.gutterMedium}; + border-bottom: ${({ theme }) => theme.eui.euiBorderThin}; +`; export function ApmHeader({ children }: { children: ReactNode }) { return ( - <> - - {children} - - - - - - - - - - - - - - - - + + {children} + + + + ); } diff --git a/x-pack/plugins/apm/public/components/shared/EnvironmentFilter/index.tsx b/x-pack/plugins/apm/public/components/shared/EnvironmentFilter/index.tsx index e6e40e44bad38..cace4c2770f37 100644 --- a/x-pack/plugins/apm/public/components/shared/EnvironmentFilter/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/EnvironmentFilter/index.tsx @@ -73,6 +73,11 @@ export function EnvironmentFilter() { end, }); + // Set the min-width so we don't see as much collapsing of the select during + // the loading state. 200px is what is looks like if "production" is + // the contents. + const minWidth = 200; + return ( ); } diff --git a/x-pack/plugins/apm/public/components/shared/EuiTabLink.tsx b/x-pack/plugins/apm/public/components/shared/EuiTabLink.tsx deleted file mode 100644 index d29ccd8abcd42..0000000000000 --- a/x-pack/plugins/apm/public/components/shared/EuiTabLink.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 cls from 'classnames'; -import styled from 'styled-components'; -import { px, unit } from '../../style/variables'; - -// TODO: replace this component with EUITab w/ a href prop -// as soon as EUI is upgraded to 13.8.1 -// see https://github.com/elastic/eui/pull/2275 - -interface Props { - isSelected: boolean; - children: React.ReactNode; -} - -// We need to remove padding and add it to the link, -// to prevent the user from clicking in the tab, but outside of the link -// We also need to override the color here to subdue the color of the link -// when not selected - -const Wrapper = styled.div<{ isSelected: boolean }>` - padding: 0; - a { - display: inline-block; - padding: ${px(unit * 0.75)} ${px(unit)}; - ${({ isSelected, theme }) => - !isSelected ? `color: ${theme.eui.euiTextColor} !important;` : ''} - } -`; - -function EuiTabLink(props: Props) { - const { isSelected, children } = props; - - const className = cls('euiTab', { - 'euiTab-isSelected': isSelected, - }); - - return ( - - {children} - - ); -} - -export { EuiTabLink }; diff --git a/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx b/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx index 157e014bee424..df1dac8dbdb5d 100644 --- a/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx @@ -80,13 +80,6 @@ export function KueryBar() { }, }); - // The bar should be disabled when viewing the service map - const disabled = /\/(service-map)$/.test(location.pathname); - const disabledPlaceholder = i18n.translate( - 'xpack.apm.kueryBar.disabledPlaceholder', - { defaultMessage: 'Search is not available here' } - ); - async function onChange(inputValue: string, selectionStart: number) { if (indexPattern == null) { return; @@ -152,13 +145,12 @@ export function KueryBar() { return ( ); diff --git a/x-pack/plugins/apm/public/components/shared/main_tabs.tsx b/x-pack/plugins/apm/public/components/shared/main_tabs.tsx new file mode 100644 index 0000000000000..08d23cad817bf --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/main_tabs.tsx @@ -0,0 +1,26 @@ +/* + * 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 { EuiTabs } from '@elastic/eui'; +import React, { ReactNode } from 'react'; +import styled from 'styled-components'; + +// Since our `EuiTab` components have `APMLink`s inside of them and not just +// `href`s, we need to override the color of the links inside or they will all +// be the primary color. +const StyledTabs = styled(EuiTabs)` + padding: ${({ theme }) => + `${theme.eui.gutterTypes.gutterMedium} ${theme.eui.gutterTypes.gutterLarge}`}; + border-bottom: ${({ theme }) => theme.eui.euiBorderThin}; + + .euiLink { + color: inherit; + } +`; + +export function MainTabs({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/x-pack/plugins/apm/public/components/shared/search_bar.tsx b/x-pack/plugins/apm/public/components/shared/search_bar.tsx new file mode 100644 index 0000000000000..686df42cf3b8a --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/search_bar.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 { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React from 'react'; +import styled from 'styled-components'; +import { DatePicker } from './DatePicker'; +import { KueryBar } from './KueryBar'; + +const SearchBarFlexGroup = styled(EuiFlexGroup)` + margin: ${({ theme }) => + `${theme.eui.euiSizeM} ${theme.eui.euiSizeM} -${theme.eui.gutterTypes.gutterMedium} ${theme.eui.euiSizeM}`}; +`; + +export function SearchBar() { + return ( + + + + + + + + + ); +} diff --git a/x-pack/plugins/observability/public/components/app/header/index.tsx b/x-pack/plugins/observability/public/components/app/header/index.tsx index 543ca2c3b3232..8257dce3fb40b 100644 --- a/x-pack/plugins/observability/public/components/app/header/index.tsx +++ b/x-pack/plugins/observability/public/components/app/header/index.tsx @@ -53,7 +53,7 @@ export function Header({ - +

{i18n.translate('xpack.observability.home.title', { defaultMessage: 'Observability', diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 85f0290cb5b1d..95cd6cafb121b 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4939,7 +4939,6 @@ "xpack.apm.jvmsTable.noJvmsLabel": "JVM が見つかりませんでした", "xpack.apm.jvmsTable.nonHeapMemoryColumnLabel": "非ヒープ領域の平均", "xpack.apm.jvmsTable.threadCountColumnLabel": "最大スレッド数", - "xpack.apm.kueryBar.disabledPlaceholder": "ここでは検索は利用できません", "xpack.apm.license.betaBadge": "ベータ", "xpack.apm.license.betaTooltipMessage": "現在、この機能はベータです。不具合を見つけた場合やご意見がある場合、サポートに問い合わせるか、またはディスカッションフォーラムにご報告ください。", "xpack.apm.license.button": "トライアルを開始", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 59399d9278aa0..717047e18dda6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4941,7 +4941,6 @@ "xpack.apm.jvmsTable.noJvmsLabel": "未找到任何 JVM", "xpack.apm.jvmsTable.nonHeapMemoryColumnLabel": "非堆内存平均值", "xpack.apm.jvmsTable.threadCountColumnLabel": "线程计数最大值", - "xpack.apm.kueryBar.disabledPlaceholder": "搜索在此不可用", "xpack.apm.kueryBar.placeholder": "搜索{event, select,\n transaction {事务}\n metric {指标}\n error {错误}\n other {事务、错误和指标}\n }(例如 {queryExample})", "xpack.apm.license.betaBadge": "公测版", "xpack.apm.license.betaTooltipMessage": "此功能当前为公测版。如果遇到任何错误或有任何反馈,请报告问题或访问我们的论坛。", From efc2461f0666aa52b67d66acc7fea052f84c503a Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Sat, 7 Nov 2020 19:19:04 -0600 Subject: [PATCH 2/5] fix imports --- .../apm/public/components/app/Home/index.tsx | 2 -- .../components/app/TraceOverview/index.tsx | 16 +++++----------- .../app/service_inventory/index.tsx | 19 +++++++++---------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/Home/index.tsx b/x-pack/plugins/apm/public/components/app/Home/index.tsx index 594288b708665..c4db5f0ff1540 100644 --- a/x-pack/plugins/apm/public/components/app/Home/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Home/index.tsx @@ -8,7 +8,6 @@ import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, - EuiPage, EuiTab, EuiTitle, } from '@elastic/eui'; @@ -25,7 +24,6 @@ import { SettingsLink } from '../../shared/Links/apm/SettingsLink'; import { TraceOverviewLink } from '../../shared/Links/apm/TraceOverviewLink'; import { SetupInstructionsLink } from '../../shared/Links/SetupInstructionsLink'; import { MainTabs } from '../../shared/main_tabs'; -import { SearchBar } from '../../shared/search_bar'; import { ServiceMap } from '../ServiceMap'; import { ServiceInventory } from '../service_inventory'; import { TraceOverview } from '../TraceOverview'; diff --git a/x-pack/plugins/apm/public/components/app/TraceOverview/index.tsx b/x-pack/plugins/apm/public/components/app/TraceOverview/index.tsx index 797ec5e17ab3c..a87bbdb926a21 100644 --- a/x-pack/plugins/apm/public/components/app/TraceOverview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TraceOverview/index.tsx @@ -4,22 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - EuiPanel, - EuiFlexGroup, - EuiFlexItem, - EuiPage, - EuiSpacer, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiPage, EuiPanel } from '@elastic/eui'; import React, { useMemo } from 'react'; -import { FETCH_STATUS, useFetcher } from '../../../hooks/useFetcher'; -import { TraceList } from './TraceList'; -import { useUrlParams } from '../../../hooks/useUrlParams'; import { useTrackPageview } from '../../../../../observability/public'; -import { LocalUIFilters } from '../../shared/LocalUIFilters'; import { Projection } from '../../../../common/projections'; +import { FETCH_STATUS, useFetcher } from '../../../hooks/useFetcher'; +import { useUrlParams } from '../../../hooks/useUrlParams'; import { APIReturnType } from '../../../services/rest/createCallApmApi'; +import { LocalUIFilters } from '../../shared/LocalUIFilters'; import { SearchBar } from '../../shared/search_bar'; +import { TraceList } from './TraceList'; type TracesAPIResponse = APIReturnType<'/api/apm/traces'>; const DEFAULT_RESPONSE: TracesAPIResponse = { diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx index 61e78200a5316..7a5893314ddf0 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx @@ -5,30 +5,29 @@ */ import { - EuiPanel, EuiFlexGroup, EuiFlexItem, EuiLink, EuiPage, - EuiSpacer, + EuiPanel, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useMemo } from 'react'; import url from 'url'; import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public'; -import { useFetcher, FETCH_STATUS } from '../../../hooks/useFetcher'; -import { NoServicesMessage } from './no_services_message'; -import { ServiceList } from './ServiceList'; -import { useUrlParams } from '../../../hooks/useUrlParams'; import { useTrackPageview } from '../../../../../observability/public'; import { Projection } from '../../../../common/projections'; -import { LocalUIFilters } from '../../shared/LocalUIFilters'; +import { useAnomalyDetectionJobs } from '../../../hooks/useAnomalyDetectionJobs'; import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; -import { MLCallout } from './ServiceList/MLCallout'; +import { FETCH_STATUS, useFetcher } from '../../../hooks/useFetcher'; import { useLocalStorage } from '../../../hooks/useLocalStorage'; -import { useAnomalyDetectionJobs } from '../../../hooks/useAnomalyDetectionJobs'; -import { Correlations } from '../Correlations'; +import { useUrlParams } from '../../../hooks/useUrlParams'; +import { LocalUIFilters } from '../../shared/LocalUIFilters'; import { SearchBar } from '../../shared/search_bar'; +import { Correlations } from '../Correlations'; +import { NoServicesMessage } from './no_services_message'; +import { ServiceList } from './ServiceList'; +import { MLCallout } from './ServiceList/MLCallout'; const initialData = { items: [], From 13d8523c278aaf151f8a637b1bf808a800e6ecae Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Tue, 10 Nov 2020 17:24:29 -0600 Subject: [PATCH 3/5] Redo tabs --- .../apm/public/components/app/Home/index.tsx | 98 ++++++------- .../app/ServiceDetails/ServiceDetailTabs.tsx | 130 +++++++++--------- .../components/app/ServiceMap/index.tsx | 6 +- .../components/shared/Links/apm/APMLink.tsx | 19 ++- .../shared/Links/apm/ErrorOverviewLink.tsx | 32 ++--- .../shared/Links/apm/MetricOverviewLink.tsx | 30 ++-- .../shared/Links/apm/ServiceMapLink.tsx | 24 ++-- .../Links/apm/ServiceNodeOverviewLink.tsx | 28 ++-- .../shared/Links/apm/TraceOverviewLink.tsx | 34 +++-- .../Links/apm/TransactionOverviewLink.tsx | 30 ++-- .../Links/apm/service_inventory_link.tsx | 19 ++- .../Links/apm/service_overview_link.tsx | 6 +- .../public/components/shared/main_tabs.tsx | 7 +- 13 files changed, 238 insertions(+), 225 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/Home/index.tsx b/x-pack/plugins/apm/public/components/app/Home/index.tsx index c4db5f0ff1540..1d749cc3088d8 100644 --- a/x-pack/plugins/apm/public/components/app/Home/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Home/index.tsx @@ -12,16 +12,16 @@ import { EuiTitle, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React from 'react'; +import React, { ComponentType } from 'react'; import { $ElementType } from 'utility-types'; import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; import { getAlertingCapabilities } from '../../alerting/get_alert_capabilities'; import { ApmHeader } from '../../shared/ApmHeader'; import { AnomalyDetectionSetupLink } from '../../shared/Links/apm/AnomalyDetectionSetupLink'; -import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; -import { ServiceInventoryLink } from '../../shared/Links/apm/service_inventory_link'; +import { useServiceMapHref } from '../../shared/Links/apm/ServiceMapLink'; +import { useServiceInventoryHref } from '../../shared/Links/apm/service_inventory_link'; import { SettingsLink } from '../../shared/Links/apm/SettingsLink'; -import { TraceOverviewLink } from '../../shared/Links/apm/TraceOverviewLink'; +import { useTraceOverviewHref } from '../../shared/Links/apm/TraceOverviewLink'; import { SetupInstructionsLink } from '../../shared/Links/SetupInstructionsLink'; import { MainTabs } from '../../shared/main_tabs'; import { ServiceMap } from '../ServiceMap'; @@ -29,51 +29,11 @@ import { ServiceInventory } from '../service_inventory'; import { TraceOverview } from '../TraceOverview'; import { AlertingPopoverAndFlyout } from './alerting_popover_flyout'; -function getHomeTabs({ - serviceMapEnabled = true, -}: { - serviceMapEnabled: boolean; -}) { - const homeTabs = [ - { - link: ( - - {i18n.translate('xpack.apm.home.servicesTabLabel', { - defaultMessage: 'Services', - })} - - ), - render: () => , - name: 'services', - }, - { - link: ( - - {i18n.translate('xpack.apm.home.tracesTabLabel', { - defaultMessage: 'Traces', - })} - - ), - render: () => , - name: 'traces', - }, - ]; - - if (serviceMapEnabled) { - homeTabs.push({ - link: ( - - {i18n.translate('xpack.apm.home.serviceMapTabLabel', { - defaultMessage: 'Service Map', - })} - - ), - render: () => , - name: 'service-map', - }); - } - - return homeTabs; +interface Tab { + key: string; + href: string; + text: string; + Component: ComponentType; } const SETTINGS_LINK_LABEL = i18n.translate('xpack.apm.settingsLinkLabel', { @@ -85,12 +45,38 @@ interface Props { } export function Home({ tab }: Props) { - const { config, core, plugins } = useApmPluginContext(); + const { core, plugins } = useApmPluginContext(); + + const homeTabs: Tab[] = [ + { + key: 'services', + href: useServiceInventoryHref(), + text: i18n.translate('xpack.apm.home.servicesTabLabel', { + defaultMessage: 'Services', + }), + Component: ServiceInventory, + }, + { + key: 'traces', + href: useTraceOverviewHref(), + text: i18n.translate('xpack.apm.home.tracesTabLabel', { + defaultMessage: 'Traces', + }), + Component: TraceOverview, + }, + { + key: 'service-map', + href: useServiceMapHref(), + text: i18n.translate('xpack.apm.home.serviceMapTabLabel', { + defaultMessage: 'Service Map', + }), + Component: ServiceMap, + }, + ]; const capabilities = core.application.capabilities; const canAccessML = !!capabilities.ml?.canAccessML; - const homeTabs = getHomeTabs(config); const selectedTab = homeTabs.find( - (homeTab) => homeTab.name === tab + (homeTab) => homeTab.key === tab ) as $ElementType; const { @@ -136,13 +122,13 @@ export function Home({ tab }: Props) { - {homeTabs.map((homeTab) => ( - - {homeTab.link} + {homeTabs.map(({ href, key, text }) => ( + + {text} ))} - {selectedTab.render()} + ); } 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 2351bdebfba3a..f42b94b8afe33 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx @@ -6,17 +6,17 @@ import { EuiTab } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React from 'react'; +import React, { ReactNode } from 'react'; import { isJavaAgentName, isRumAgentName } from '../../../../common/agent_name'; import { enableServiceOverview } from '../../../../common/ui_settings_keys'; import { useAgentName } from '../../../hooks/useAgentName'; import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; -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 { 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 { useTransactionOverviewHref } from '../../shared/Links/apm/TransactionOverviewLink'; import { MainTabs } from '../../shared/main_tabs'; import { ErrorGroupOverview } from '../ErrorGroupOverview'; import { ServiceMap } from '../ServiceMap'; @@ -25,6 +25,13 @@ import { ServiceNodeOverview } from '../ServiceNodeOverview'; import { ServiceOverview } from '../service_overview'; import { TransactionOverview } from '../TransactionOverview'; +interface Tab { + key: string; + href: string; + text: string; + render: () => ReactNode; +} + interface Props { serviceName: string; tab: @@ -41,101 +48,88 @@ export function ServiceDetailTabs({ serviceName, tab }: Props) { const { uiSettings } = useApmPluginContext().core; const overviewTab = { - link: ( - - {i18n.translate('xpack.apm.serviceDetails.overviewTabLabel', { - defaultMessage: 'Overview', - })} - - ), + key: 'overview', + href: useServiceOverviewHref(serviceName), + text: i18n.translate('xpack.apm.serviceDetails.overviewTabLabel', { + defaultMessage: 'Overview', + }), render: () => ( ), - name: 'overview', }; const transactionsTab = { - link: ( - - {i18n.translate('xpack.apm.serviceDetails.transactionsTabLabel', { - defaultMessage: 'Transactions', - })} - - ), + key: 'transactions', + href: useTransactionOverviewHref(serviceName), + text: i18n.translate('xpack.apm.serviceDetails.transactionsTabLabel', { + defaultMessage: 'Transactions', + }), render: () => , - name: 'transactions', }; const errorsTab = { - link: ( - - {i18n.translate('xpack.apm.serviceDetails.errorsTabLabel', { - defaultMessage: 'Errors', - })} - - ), + key: 'errors', + href: useErrorOverviewHref(serviceName), + text: i18n.translate('xpack.apm.serviceDetails.errorsTabLabel', { + defaultMessage: 'Errors', + }), render: () => { return ; }, - name: 'errors', }; const serviceMapTab = { - link: ( - - {i18n.translate('xpack.apm.home.serviceMapTabLabel', { - defaultMessage: 'Service Map', - })} - - ), + key: 'service-map', + href: useServiceMapHref(serviceName), + text: i18n.translate('xpack.apm.home.serviceMapTabLabel', { + defaultMessage: 'Service Map', + }), render: () => , - name: 'service-map', }; - const tabs = [transactionsTab, errorsTab, serviceMapTab]; + const nodesListTab = { + key: 'nodes', + href: useServiceNodeOverviewHref(serviceName), + text: i18n.translate('xpack.apm.serviceDetails.nodesTabLabel', { + defaultMessage: 'JVMs', + }), + render: () => , + }; + + const metricsTab = { + key: 'metrics', + href: useMetricOverviewHref(serviceName), + text: i18n.translate('xpack.apm.serviceDetails.metricsTabLabel', { + defaultMessage: 'Metrics', + }), + render: () => + agentName ? ( + + ) : null, + }; + + const tabs: Tab[] = [transactionsTab, errorsTab]; if (uiSettings.get(enableServiceOverview)) { tabs.unshift(overviewTab); } if (isJavaAgentName(agentName)) { - const nodesListTab = { - link: ( - - {i18n.translate('xpack.apm.serviceDetails.nodesTabLabel', { - defaultMessage: 'JVMs', - })} - - ), - render: () => , - name: 'nodes', - }; tabs.push(nodesListTab); } else if (agentName && !isRumAgentName(agentName)) { - const metricsTab = { - link: ( - - {i18n.translate('xpack.apm.serviceDetails.metricsTabLabel', { - defaultMessage: 'Metrics', - })} - - ), - render: () => ( - - ), - name: 'metrics', - }; tabs.push(metricsTab); } - const selectedTab = tabs.find((serviceTab) => serviceTab.name === tab); + tabs.push(serviceMapTab); + + const selectedTab = tabs.find((serviceTab) => serviceTab.key === tab); return ( <> - {tabs.map((serviceTab) => ( - - {serviceTab.link} + {tabs.map(({ href, key, text }) => ( + + {text} ))} diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx index d5a9b2a0c917a..15adf8a70d357 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx @@ -5,7 +5,7 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; -import React, { ReactNode } from 'react'; +import React, { PropsWithChildren, ReactNode } from 'react'; import styled from 'styled-components'; import { useTrackPageview } from '../../../../../observability/public'; import { @@ -66,7 +66,9 @@ function LoadingSpinner() { ); } -export function ServiceMap({ serviceName }: ServiceMapProps) { +export function ServiceMap({ + serviceName, +}: PropsWithChildren) { const theme = useTheme(); const license = useLicense(); const { urlParams } = useUrlParams(); diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx index bd43f2455c545..41c932bf9c9f5 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx @@ -10,7 +10,9 @@ import { pick } from 'lodash'; import React from 'react'; import { useLocation } from 'react-router-dom'; import url from 'url'; +import { pickKeys } from '../../../../../common/utils/pick_keys'; import { useApmPluginContext } from '../../../../hooks/useApmPluginContext'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; import { APMQueryParams, fromQuery, toQuery } from '../url_helpers'; interface Props extends EuiLinkAnchorProps { @@ -21,7 +23,7 @@ interface Props extends EuiLinkAnchorProps { export type APMLinkExtendProps = Omit; -export const PERSISTENT_APM_PARAMS = [ +export const PERSISTENT_APM_PARAMS: Array = [ 'kuery', 'rangeFrom', 'rangeTo', @@ -30,6 +32,21 @@ export const PERSISTENT_APM_PARAMS = [ 'environment', ]; +/** + * Hook to get a link for a path with persisted filters + */ +export function useAPMHref( + path: string, + persistentFilters: Array = PERSISTENT_APM_PARAMS +) { + const { urlParams } = useUrlParams(); + const { basePath } = useApmPluginContext().core.http; + const { search } = useLocation(); + const query = pickKeys(urlParams as APMQueryParams, ...persistentFilters); + + return getAPMHref({ basePath, path, query, search }); +} + /** * Get an APM link for a path. */ diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx index 862b1ac649648..5cb20e353131e 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx @@ -4,37 +4,35 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { APMLink, APMLinkExtendProps } from './APMLink'; -import { useUrlParams } from '../../../../hooks/useUrlParams'; import { pickKeys } from '../../../../../common/utils/pick_keys'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; import { APMQueryParams } from '../url_helpers'; +import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink'; + +const persistedFilters: Array = [ + 'host', + 'containerId', + 'podName', + 'serviceVersion', +]; + +export function useErrorOverviewHref(serviceName: string) { + return useAPMHref(`/services/${serviceName}/errors`, persistedFilters); +} interface Props extends APMLinkExtendProps { serviceName: string; query?: APMQueryParams; } -function ErrorOverviewLink({ serviceName, query, ...rest }: Props) { +export function ErrorOverviewLink({ serviceName, query, ...rest }: Props) { const { urlParams } = useUrlParams(); - const persistedFilters = pickKeys( - urlParams, - 'host', - 'containerId', - 'podName', - 'serviceVersion' - ); - return ( ); } - -export { ErrorOverviewLink }; diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/MetricOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/MetricOverviewLink.tsx index 35ba5db68d507..fbae80203f03b 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/MetricOverviewLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/MetricOverviewLink.tsx @@ -4,32 +4,34 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { APMLink, APMLinkExtendProps } from './APMLink'; -import { useUrlParams } from '../../../../hooks/useUrlParams'; import { pickKeys } from '../../../../../common/utils/pick_keys'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; +import { APMQueryParams } from '../url_helpers'; +import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink'; + +const persistedFilters: Array = [ + 'host', + 'containerId', + 'podName', + 'serviceVersion', +]; + +export function useMetricOverviewHref(serviceName: string) { + return useAPMHref(`/services/${serviceName}/metrics`, persistedFilters); +} interface Props extends APMLinkExtendProps { serviceName: string; } -function MetricOverviewLink({ serviceName, ...rest }: Props) { +export function MetricOverviewLink({ serviceName, ...rest }: Props) { const { urlParams } = useUrlParams(); - const persistedFilters = pickKeys( - urlParams, - 'host', - 'containerId', - 'podName', - 'serviceVersion' - ); - return ( ); } - -export { MetricOverviewLink }; diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceMapLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceMapLink.tsx index ff8b1354daeb5..ae5dc86608a90 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceMapLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceMapLink.tsx @@ -1,26 +1,24 @@ -/* - * 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'; +import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink'; + +function pathFor(serviceName?: string) { + return serviceName ? `/services/${serviceName}/service-map` : '/service-map'; +} + +export function useServiceMapHref(serviceName?: string) { + return useAPMHref(pathFor(serviceName)); +} interface ServiceMapLinkProps extends APMLinkExtendProps { serviceName?: string; } -function ServiceMapLink({ serviceName, ...rest }: ServiceMapLinkProps) { - const path = serviceName - ? `/services/${serviceName}/service-map` - : '/service-map'; +export function ServiceMapLink({ serviceName, ...rest }: ServiceMapLinkProps) { + const path = pathFor(serviceName); return ; } - -export { ServiceMapLink }; diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeOverviewLink.tsx index 111c2391cd54f..0a9553bcbfe6c 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeOverviewLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeOverviewLink.tsx @@ -4,32 +4,34 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { APMLink, APMLinkExtendProps } from './APMLink'; +import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink'; import { useUrlParams } from '../../../../hooks/useUrlParams'; import { pickKeys } from '../../../../../common/utils/pick_keys'; +import { APMQueryParams } from '../url_helpers'; + +const persistedFilters: Array = [ + 'host', + 'containerId', + 'podName', + 'serviceVersion', +]; + +export function useServiceNodeOverviewHref(serviceName: string) { + return useAPMHref(`/services/${serviceName}/nodes`, persistedFilters); +} interface Props extends APMLinkExtendProps { serviceName: string; } -function ServiceNodeOverviewLink({ serviceName, ...rest }: Props) { +export function ServiceNodeOverviewLink({ serviceName, ...rest }: Props) { const { urlParams } = useUrlParams(); - const persistedFilters = pickKeys( - urlParams, - 'host', - 'containerId', - 'podName', - 'serviceVersion' - ); - return ( ); } - -export { ServiceNodeOverviewLink }; diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/TraceOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/TraceOverviewLink.tsx index 8f3ea191fab1a..6aa362707800f 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/TraceOverviewLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/TraceOverviewLink.tsx @@ -10,22 +10,30 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { APMLink, APMLinkExtendProps } from './APMLink'; -import { useUrlParams } from '../../../../hooks/useUrlParams'; import { pickKeys } from '../../../../../common/utils/pick_keys'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; +import { APMQueryParams } from '../url_helpers'; +import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink'; -function TraceOverviewLink(props: APMLinkExtendProps) { +const persistedFilters: Array = [ + 'transactionResult', + 'host', + 'containerId', + 'podName', +]; + +export function useTraceOverviewHref() { + return useAPMHref('/traces', persistedFilters); +} + +export function TraceOverviewLink(props: APMLinkExtendProps) { const { urlParams } = useUrlParams(); - const persistedFilters = pickKeys( - urlParams, - 'transactionResult', - 'host', - 'containerId', - 'podName' + return ( + ); - - return ; } - -export { TraceOverviewLink }; diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/TransactionOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/TransactionOverviewLink.tsx index adc64f5a2d3dc..23e795b026d0c 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/TransactionOverviewLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/TransactionOverviewLink.tsx @@ -4,33 +4,35 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { APMLink, APMLinkExtendProps } from './APMLink'; +import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink'; import { useUrlParams } from '../../../../hooks/useUrlParams'; import { pickKeys } from '../../../../../common/utils/pick_keys'; +import { APMQueryParams } from '../url_helpers'; + +const persistedFilters: Array = [ + 'transactionResult', + 'host', + 'containerId', + 'podName', + 'serviceVersion', +]; + +export function useTransactionOverviewHref(serviceName: string) { + return useAPMHref(`/services/${serviceName}/transactions`, persistedFilters); +} interface Props extends APMLinkExtendProps { serviceName: string; } -function TransactionOverviewLink({ serviceName, ...rest }: Props) { +export function TransactionOverviewLink({ serviceName, ...rest }: Props) { const { urlParams } = useUrlParams(); - const persistedFilters = pickKeys( - urlParams, - 'transactionResult', - 'host', - 'containerId', - 'podName', - 'serviceVersion' - ); - return ( ); } - -export { TransactionOverviewLink }; diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx index e3fa03a4d4f86..039d9dcb1c0ed 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx @@ -10,16 +10,21 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { APMLink, APMLinkExtendProps } from './APMLink'; -import { useUrlParams } from '../../../../hooks/useUrlParams'; import { pickKeys } from '../../../../../common/utils/pick_keys'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; +import { APMQueryParams } from '../url_helpers'; +import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink'; + +const persistedFilters: Array = ['host', 'agentName']; -function ServiceInventoryLink(props: APMLinkExtendProps) { +export function useServiceInventoryHref() { + return useAPMHref('/services', persistedFilters); +} + +export function ServiceInventoryLink(props: APMLinkExtendProps) { const { urlParams } = useUrlParams(); - const persistedFilters = pickKeys(urlParams, 'host', 'agentName'); + const query = pickKeys(urlParams as APMQueryParams, ...persistedFilters); - return ; + return ; } - -export { ServiceInventoryLink }; 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 index 5d7859e7362c7..78e409bb4558c 100644 --- 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 @@ -9,12 +9,16 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { APMLink, APMLinkExtendProps } from './APMLink'; +import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink'; interface ServiceOverviewLinkProps extends APMLinkExtendProps { serviceName: string; } +export function useServiceOverviewHref(serviceName: string) { + return useAPMHref(`/services/${serviceName}/overview`); +} + export function ServiceOverviewLink({ serviceName, ...rest diff --git a/x-pack/plugins/apm/public/components/shared/main_tabs.tsx b/x-pack/plugins/apm/public/components/shared/main_tabs.tsx index 08d23cad817bf..a165cabec857c 100644 --- a/x-pack/plugins/apm/public/components/shared/main_tabs.tsx +++ b/x-pack/plugins/apm/public/components/shared/main_tabs.tsx @@ -12,13 +12,8 @@ import styled from 'styled-components'; // `href`s, we need to override the color of the links inside or they will all // be the primary color. const StyledTabs = styled(EuiTabs)` - padding: ${({ theme }) => - `${theme.eui.gutterTypes.gutterMedium} ${theme.eui.gutterTypes.gutterLarge}`}; + padding: ${({ theme }) => `${theme.eui.gutterTypes.gutterMedium}`}; border-bottom: ${({ theme }) => theme.eui.euiBorderThin}; - - .euiLink { - color: inherit; - } `; export function MainTabs({ children }: { children: ReactNode }) { From cd386f8961964687b2ec4ff24269716b519284b9 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Wed, 11 Nov 2020 15:53:53 -0600 Subject: [PATCH 4/5] fixes --- .../public/components/shared/Links/apm/ErrorOverviewLink.tsx | 5 ++++- .../apm/server/lib/alerts/register_error_count_alert_type.ts | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx index 5cb20e353131e..30b91fe2564f1 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx @@ -31,7 +31,10 @@ export function ErrorOverviewLink({ serviceName, query, ...rest }: Props) { return ( ); diff --git a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts index 7b63f2c354916..ecda5b0e8504b 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts @@ -66,6 +66,7 @@ export function registerErrorCountAlertType({ config, savedObjectsClient: services.savedObjectsClient, }); + const maxServiceEnvironments = config['xpack.apm.maxServiceEnvironments']; const searchParams = { index: indices['apm_oss.errorIndices'], @@ -100,6 +101,7 @@ export function registerErrorCountAlertType({ environments: { terms: { field: SERVICE_ENVIRONMENT, + size: maxServiceEnvironments, }, }, }, From e472d7600a75bb086bd86ea487a118f6f1d0679d Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Thu, 12 Nov 2020 14:06:37 -0600 Subject: [PATCH 5/5] test fixes --- .../TransactionOverview.test.tsx | 8 ++- .../service_inventory.test.tsx | 31 +++++++----- .../service_overview.test.tsx | 50 +++++++++++++++++-- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/TransactionOverview.test.tsx b/x-pack/plugins/apm/public/components/app/TransactionOverview/TransactionOverview.test.tsx index c530a7e1489ad..2d7992feb3760 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/TransactionOverview.test.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/TransactionOverview.test.tsx @@ -119,14 +119,18 @@ describe('TransactionOverview', () => { }, }); - expect(history.location.search).toEqual('?transactionType=secondType'); + expect(history.location.search).toEqual( + '?transactionType=secondType&rangeFrom=now-15m&rangeTo=now' + ); expect(getByText(container, 'firstType')).toBeInTheDocument(); expect(getByText(container, 'secondType')).toBeInTheDocument(); fireEvent.click(getByText(container, 'firstType')); expect(history.push).toHaveBeenCalled(); - expect(history.location.search).toEqual('?transactionType=firstType'); + expect(history.location.search).toEqual( + '?transactionType=firstType&rangeFrom=now-15m&rangeTo=now' + ); }); }); diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/service_inventory.test.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/service_inventory.test.tsx index 247e91fb438ef..de5e92664a769 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/service_inventory.test.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/service_inventory.test.tsx @@ -21,8 +21,9 @@ import { import * as useAnomalyDetectionJobs from '../../../hooks/useAnomalyDetectionJobs'; import { FETCH_STATUS } from '../../../hooks/useFetcher'; import * as useLocalUIFilters from '../../../hooks/useLocalUIFilters'; -import * as urlParamsHooks from '../../../hooks/useUrlParams'; +import * as useDynamicIndexPatternHooks from '../../../hooks/useDynamicIndexPattern'; import { SessionStorageMock } from '../../../services/__test__/SessionStorageMock'; +import { MockUrlParamsContextProvider } from '../../../context/UrlParamsContext/MockUrlParamsContextProvider'; const KibanaReactContext = createKibanaReactContext({ usageCollection: { reportUiStats: () => {} }, @@ -50,7 +51,16 @@ function wrapper({ children }: { children?: ReactNode }) { - {children} + + {children} + @@ -63,16 +73,6 @@ describe('ServiceInventory', () => { // @ts-expect-error global.sessionStorage = new SessionStorageMock(); - // mock urlParams - jest.spyOn(urlParamsHooks, 'useUrlParams').mockReturnValue({ - urlParams: { - start: 'myStart', - end: 'myEnd', - }, - refreshTimeRange: jest.fn(), - uiFilters: {}, - }); - jest.spyOn(useLocalUIFilters, 'useLocalUIFilters').mockReturnValue({ filters: [], setFilterValue: () => null, @@ -90,6 +90,13 @@ describe('ServiceInventory', () => { }, refetch: () => undefined, }); + + jest + .spyOn(useDynamicIndexPatternHooks, 'useDynamicIndexPattern') + .mockReturnValue({ + indexPattern: undefined, + status: FETCH_STATUS.SUCCESS, + }); }); afterEach(() => { 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 index 210d353303854..8f9e76a5a79a6 100644 --- 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 @@ -8,7 +8,15 @@ import React, { ReactNode } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { CoreStart } from 'src/core/public'; import { createKibanaReactContext } from '../../../../../../../src/plugins/kibana_react/public'; -import { MockApmPluginContextWrapper } from '../../../context/ApmPluginContext/MockApmPluginContext'; +import { ApmPluginContextValue } from '../../../context/ApmPluginContext'; +import { + mockApmPluginContextValue, + MockApmPluginContextWrapper, +} from '../../../context/ApmPluginContext/MockApmPluginContext'; +import { MockUrlParamsContextProvider } from '../../../context/UrlParamsContext/MockUrlParamsContextProvider'; +import * as useDynamicIndexPatternHooks from '../../../hooks/useDynamicIndexPattern'; +import * as useFetcherHooks from '../../../hooks/useFetcher'; +import { FETCH_STATUS } from '../../../hooks/useFetcher'; import { renderWithTheme } from '../../../utils/testHelpers'; import { ServiceOverview } from './'; @@ -17,10 +25,27 @@ const KibanaReactContext = createKibanaReactContext({ } as Partial); function Wrapper({ children }: { children?: ReactNode }) { + const value = ({ + ...mockApmPluginContextValue, + core: { + ...mockApmPluginContextValue.core, + http: { + basePath: { prepend: () => {} }, + get: () => {}, + }, + }, + } as unknown) as ApmPluginContextValue; + return ( - + - {children} + + + {children} + + ); @@ -28,6 +53,25 @@ function Wrapper({ children }: { children?: ReactNode }) { describe('ServiceOverview', () => { it('renders', () => { + jest + .spyOn(useDynamicIndexPatternHooks, 'useDynamicIndexPattern') + .mockReturnValue({ + indexPattern: undefined, + status: FETCH_STATUS.SUCCESS, + }); + jest.spyOn(useFetcherHooks, 'useFetcher').mockReturnValue({ + data: { + items: [], + tableOptions: { + pageIndex: 0, + sort: { direction: 'desc', field: 'test field' }, + }, + totalItemCount: 0, + }, + refetch: () => {}, + status: FETCH_STATUS.SUCCESS, + }); + expect(() => renderWithTheme(, { wrapper: Wrapper,