Remove UI filters from UI (#89793)
* Start moving some stuff * Move some stuff around * more * Transactions label * some snake casing * i18n fix * Remove unused ui filters endpoints * Updates to select * remove projections * Use urlHelpers.push * License change
This commit is contained in:
parent
54b1fb6163
commit
85e92b5ccd
|
@ -1,17 +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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export enum Projection {
|
||||
services = 'services',
|
||||
transactionGroups = 'transactionGroups',
|
||||
traces = 'traces',
|
||||
transactions = 'transactions',
|
||||
metrics = 'metrics',
|
||||
errorGroups = 'errorGroups',
|
||||
serviceNodes = 'serviceNodes',
|
||||
rumOverview = 'rumOverview',
|
||||
}
|
|
@ -16,7 +16,7 @@ import { useTraceOverviewHref } from '../../shared/Links/apm/TraceOverviewLink';
|
|||
import { MainTabs } from '../../shared/main_tabs';
|
||||
import { ServiceMap } from '../ServiceMap';
|
||||
import { ServiceInventory } from '../service_inventory';
|
||||
import { TraceOverview } from '../TraceOverview';
|
||||
import { TraceOverview } from '../trace_overview';
|
||||
|
||||
interface Tab {
|
||||
key: string;
|
||||
|
|
|
@ -23,7 +23,7 @@ import { AnomalyDetection } from '../../Settings/anomaly_detection';
|
|||
import { ApmIndices } from '../../Settings/ApmIndices';
|
||||
import { CustomizeUI } from '../../Settings/CustomizeUI';
|
||||
import { TraceLink } from '../../TraceLink';
|
||||
import { TransactionDetails } from '../../TransactionDetails';
|
||||
import { TransactionDetails } from '../../transaction_details';
|
||||
import {
|
||||
CreateAgentConfigurationRouteHandler,
|
||||
EditAgentConfigurationRouteHandler,
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { EuiFlexGrid, EuiFlexItem, EuiBadge } from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { unit, px, truncate } from '../../../../style/variables';
|
||||
import { unit, px, truncate } from '../../../../../style/variables';
|
||||
|
||||
const BadgeText = styled.div`
|
||||
display: inline-block;
|
|
@ -21,7 +21,7 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import styled from 'styled-components';
|
||||
import { FilterBadgeList } from './FilterBadgeList';
|
||||
import { unit, px } from '../../../../style/variables';
|
||||
import { unit, px } from '../../../../../style/variables';
|
||||
import { FilterTitleButton } from './FilterTitleButton';
|
||||
|
||||
const Popover = styled((EuiPopover as unknown) as FunctionComponent).attrs(
|
|
@ -15,12 +15,10 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import styled from 'styled-components';
|
||||
import { Filter } from './Filter';
|
||||
import { useLocalUIFilters } from '../../../hooks/useLocalUIFilters';
|
||||
import { Projection } from '../../../../common/projections';
|
||||
import { LocalUIFilterName } from '../../../../common/ui_filter';
|
||||
import { useLocalUIFilters } from '../hooks/useLocalUIFilters';
|
||||
import { LocalUIFilterName } from '../../../../../common/ui_filter';
|
||||
|
||||
interface Props {
|
||||
projection: Projection;
|
||||
filterNames: LocalUIFilterName[];
|
||||
params?: Record<string, string | number | boolean | undefined>;
|
||||
showCount?: boolean;
|
||||
|
@ -33,7 +31,6 @@ const ButtonWrapper = styled.div`
|
|||
`;
|
||||
|
||||
function LocalUIFilters({
|
||||
projection,
|
||||
params,
|
||||
filterNames,
|
||||
children,
|
||||
|
@ -42,7 +39,6 @@ function LocalUIFilters({
|
|||
}: Props) {
|
||||
const { filters, setFilterValue, clearValues } = useLocalUIFilters({
|
||||
filterNames,
|
||||
projection,
|
||||
params,
|
||||
shouldFetch,
|
||||
});
|
|
@ -7,19 +7,21 @@
|
|||
|
||||
import { omit } from 'lodash';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { Projection } from '../../common/projections';
|
||||
import { pickKeys } from '../../common/utils/pick_keys';
|
||||
import { LocalUIFilterName } from '../../../../../common/ui_filter';
|
||||
import { pickKeys } from '../../../../../common/utils/pick_keys';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { LocalUIFiltersAPIResponse } from '../../server/lib/ui_filters/local_ui_filters';
|
||||
import { LocalUIFiltersAPIResponse } from '../../../../../server/lib/ui_filters/local_ui_filters';
|
||||
import {
|
||||
localUIFilters,
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
} from '../../server/lib/ui_filters/local_ui_filters/config';
|
||||
import { fromQuery, toQuery } from '../components/shared/Links/url_helpers';
|
||||
import { removeUndefinedProps } from '../context/url_params_context/helpers';
|
||||
import { useFetcher } from './use_fetcher';
|
||||
import { useUrlParams } from '../context/url_params_context/use_url_params';
|
||||
import { LocalUIFilterName } from '../../common/ui_filter';
|
||||
} from '../../../../../server/lib/ui_filters/local_ui_filters/config';
|
||||
import {
|
||||
fromQuery,
|
||||
toQuery,
|
||||
} from '../../../../components/shared/Links/url_helpers';
|
||||
import { removeUndefinedProps } from '../../../../context/url_params_context/helpers';
|
||||
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
|
||||
import { useFetcher } from '../../../../hooks/use_fetcher';
|
||||
|
||||
const getInitialData = (
|
||||
filterNames: LocalUIFilterName[]
|
||||
|
@ -31,12 +33,10 @@ const getInitialData = (
|
|||
};
|
||||
|
||||
export function useLocalUIFilters({
|
||||
projection,
|
||||
filterNames,
|
||||
params,
|
||||
shouldFetch,
|
||||
}: {
|
||||
projection: Projection;
|
||||
filterNames: LocalUIFilterName[];
|
||||
params?: Record<string, string | number | boolean | undefined>;
|
||||
shouldFetch: boolean;
|
||||
|
@ -72,7 +72,7 @@ export function useLocalUIFilters({
|
|||
(callApmApi) => {
|
||||
if (shouldFetch && urlParams.start && urlParams.end) {
|
||||
return callApmApi({
|
||||
endpoint: `GET /api/apm/ui_filters/local_filters/${projection}` as const,
|
||||
endpoint: `GET /api/apm/ui_filters/local_filters/rumOverview`,
|
||||
params: {
|
||||
query: {
|
||||
uiFilters: JSON.stringify(uiFilters),
|
||||
|
@ -87,7 +87,6 @@ export function useLocalUIFilters({
|
|||
}
|
||||
},
|
||||
[
|
||||
projection,
|
||||
uiFilters,
|
||||
urlParams.start,
|
||||
urlParams.end,
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { callApi } from '../services/rest/callApi';
|
||||
import { useApmPluginContext } from '../context/apm_plugin/use_apm_plugin_context';
|
||||
import { FetchOptions } from '../../common/fetch_options';
|
||||
import { callApi } from '../../../../services/rest/callApi';
|
||||
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
|
||||
import { FetchOptions } from '../../../../../common/fetch_options';
|
||||
|
||||
export function useCallApi() {
|
||||
const { http } = useApmPluginContext().core;
|
|
@ -5,13 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useTrackPageview } from '../../../../../observability/public';
|
||||
import { Projection } from '../../../../common/projections';
|
||||
import { LocalUIFilters } from './LocalUIFilters';
|
||||
import { RumDashboard } from './RumDashboard';
|
||||
|
||||
import { LocalUIFilters } from '../../shared/LocalUIFilters';
|
||||
import { URLFilter } from './URLFilter';
|
||||
|
||||
export function RumOverview() {
|
||||
|
@ -21,7 +19,6 @@ export function RumOverview() {
|
|||
const localUIFiltersConfig = useMemo(() => {
|
||||
const config: React.ComponentProps<typeof LocalUIFilters> = {
|
||||
filterNames: ['location', 'device', 'os', 'browser'],
|
||||
projection: Projection.rumOverview,
|
||||
};
|
||||
|
||||
return config;
|
||||
|
|
|
@ -7,29 +7,26 @@
|
|||
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPage,
|
||||
EuiPanel,
|
||||
EuiSpacer,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { useMemo } from 'react';
|
||||
import React from 'react';
|
||||
import { useTrackPageview } from '../../../../../observability/public';
|
||||
import { Projection } from '../../../../common/projections';
|
||||
import { useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { LocalUIFilters } from '../../shared/LocalUIFilters';
|
||||
import { useErrorGroupDistributionFetcher } from '../../../hooks/use_error_group_distribution_fetcher';
|
||||
import { useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { SearchBar } from '../../shared/search_bar';
|
||||
import { ErrorDistribution } from '../ErrorGroupDetails/Distribution';
|
||||
import { ErrorGroupList } from './List';
|
||||
import { useErrorGroupDistributionFetcher } from '../../../hooks/use_error_group_distribution_fetcher';
|
||||
|
||||
interface ErrorGroupOverviewProps {
|
||||
serviceName: string;
|
||||
}
|
||||
|
||||
function ErrorGroupOverview({ serviceName }: ErrorGroupOverviewProps) {
|
||||
export function ErrorGroupOverview({ serviceName }: ErrorGroupOverviewProps) {
|
||||
const { urlParams, uiFilters } = useUrlParams();
|
||||
const { start, end, sortField, sortDirection } = urlParams;
|
||||
const { errorDistributionData } = useErrorGroupDistributionFetcher({
|
||||
|
@ -68,18 +65,6 @@ function ErrorGroupOverview({ serviceName }: ErrorGroupOverviewProps) {
|
|||
});
|
||||
useTrackPageview({ app: 'apm', path: 'error_group_overview', delay: 15000 });
|
||||
|
||||
const localUIFiltersConfig = useMemo(() => {
|
||||
const config: React.ComponentProps<typeof LocalUIFilters> = {
|
||||
filterNames: ['host', 'containerId', 'podName', 'serviceVersion'],
|
||||
params: {
|
||||
serviceName,
|
||||
},
|
||||
projection: Projection.errorGroups,
|
||||
};
|
||||
|
||||
return config;
|
||||
}, [serviceName]);
|
||||
|
||||
if (!errorDistributionData || !errorGroupListData) {
|
||||
return null;
|
||||
}
|
||||
|
@ -88,41 +73,34 @@ function ErrorGroupOverview({ serviceName }: ErrorGroupOverviewProps) {
|
|||
<>
|
||||
<SearchBar />
|
||||
<EuiPage>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={1}>
|
||||
<LocalUIFilters {...localUIFiltersConfig} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={7}>
|
||||
<EuiPanel>
|
||||
<ErrorDistribution
|
||||
distribution={errorDistributionData}
|
||||
title={i18n.translate(
|
||||
'xpack.apm.serviceDetails.metrics.errorOccurrencesChartTitle',
|
||||
{
|
||||
defaultMessage: 'Error occurrences',
|
||||
}
|
||||
)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<EuiPanel>
|
||||
<ErrorDistribution
|
||||
distribution={errorDistributionData}
|
||||
title={i18n.translate(
|
||||
'xpack.apm.serviceDetails.metrics.errorOccurrencesChartTitle',
|
||||
{
|
||||
defaultMessage: 'Error occurrences',
|
||||
}
|
||||
)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<EuiPanel>
|
||||
<EuiTitle size="xs">
|
||||
<h3>Errors</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<EuiPanel>
|
||||
<EuiTitle size="xs">
|
||||
<h3>Errors</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<ErrorGroupList
|
||||
items={errorGroupListData}
|
||||
serviceName={serviceName}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<ErrorGroupList
|
||||
items={errorGroupListData}
|
||||
serviceName={serviceName}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexGroup>
|
||||
</EuiPage>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export { ErrorGroupOverview };
|
|
@ -20,9 +20,9 @@ import { useServiceNodeOverviewHref } from '../../shared/Links/apm/ServiceNodeOv
|
|||
import { useServiceOverviewHref } from '../../shared/Links/apm/service_overview_link';
|
||||
import { useTransactionsOverviewHref } from '../../shared/Links/apm/transaction_overview_link';
|
||||
import { MainTabs } from '../../shared/main_tabs';
|
||||
import { ErrorGroupOverview } from '../ErrorGroupOverview';
|
||||
import { ErrorGroupOverview } from '../error_group_overview';
|
||||
import { ServiceMap } from '../ServiceMap';
|
||||
import { ServiceNodeOverview } from '../ServiceNodeOverview';
|
||||
import { ServiceNodeOverview } from '../service_node_overview';
|
||||
import { ServiceMetrics } from '../service_metrics';
|
||||
import { ServiceOverview } from '../service_overview';
|
||||
import { TransactionOverview } from '../transaction_overview';
|
||||
|
|
|
@ -13,21 +13,19 @@ import {
|
|||
EuiPanel,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public';
|
||||
import { useTrackPageview } from '../../../../../observability/public';
|
||||
import { Projection } from '../../../../common/projections';
|
||||
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
|
||||
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { useLocalStorage } from '../../../hooks/useLocalStorage';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { LocalUIFilters } from '../../shared/LocalUIFilters';
|
||||
import { useLocalStorage } from '../../../hooks/useLocalStorage';
|
||||
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { useUpgradeAssistantHref } from '../../shared/Links/kibana';
|
||||
import { SearchBar } from '../../shared/search_bar';
|
||||
import { NoServicesMessage } from './no_services_message';
|
||||
import { ServiceList } from './ServiceList';
|
||||
import { MLCallout } from './ServiceList/MLCallout';
|
||||
import { useAnomalyDetectionJobsFetcher } from './use_anomaly_detection_jobs_fetcher';
|
||||
import { useUpgradeAssistantHref } from '../../shared/Links/kibana';
|
||||
|
||||
const initialData = {
|
||||
items: [],
|
||||
|
@ -100,16 +98,6 @@ export function ServiceInventory() {
|
|||
useTrackPageview({ app: 'apm', path: 'services_overview' });
|
||||
useTrackPageview({ app: 'apm', path: 'services_overview', delay: 15000 });
|
||||
|
||||
const localFiltersConfig: React.ComponentProps<
|
||||
typeof LocalUIFilters
|
||||
> = useMemo(
|
||||
() => ({
|
||||
filterNames: ['host', 'agentName'],
|
||||
projection: Projection.services,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const {
|
||||
anomalyDetectionJobsData,
|
||||
anomalyDetectionJobsStatus,
|
||||
|
@ -132,33 +120,24 @@ export function ServiceInventory() {
|
|||
<>
|
||||
<SearchBar showTimeComparison />
|
||||
<EuiPage>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={1}>
|
||||
<LocalUIFilters {...localFiltersConfig} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={7}>
|
||||
<EuiFlexGroup direction="column">
|
||||
{displayMlCallout ? (
|
||||
<EuiFlexItem>
|
||||
<MLCallout
|
||||
onDismiss={() => setUserHasDismissedCallout(true)}
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
{displayMlCallout ? (
|
||||
<EuiFlexItem>
|
||||
<MLCallout onDismiss={() => setUserHasDismissedCallout(true)} />
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<ServiceList
|
||||
items={servicesData.items}
|
||||
noItemsMessage={
|
||||
<NoServicesMessage
|
||||
historicalDataFound={servicesData.hasHistoricalData}
|
||||
status={servicesStatus}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<ServiceList
|
||||
items={servicesData.items}
|
||||
noItemsMessage={
|
||||
<NoServicesMessage
|
||||
historicalDataFound={servicesData.hasHistoricalData}
|
||||
status={servicesStatus}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPage>
|
||||
|
|
|
@ -20,7 +20,6 @@ import {
|
|||
MockApmPluginContextWrapper,
|
||||
} from '../../../context/apm_plugin/mock_apm_plugin_context';
|
||||
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
|
||||
import * as useLocalUIFilters from '../../../hooks/useLocalUIFilters';
|
||||
import * as useDynamicIndexPatternHooks from '../../../hooks/use_dynamic_index_pattern';
|
||||
import { SessionStorageMock } from '../../../services/__mocks__/SessionStorageMock';
|
||||
import { MockUrlParamsContextProvider } from '../../../context/url_params_context/mock_url_params_context_provider';
|
||||
|
@ -76,13 +75,6 @@ describe('ServiceInventory', () => {
|
|||
// @ts-expect-error
|
||||
global.sessionStorage = new SessionStorageMock();
|
||||
|
||||
jest.spyOn(useLocalUIFilters, 'useLocalUIFilters').mockReturnValue({
|
||||
filters: [],
|
||||
setFilterValue: () => null,
|
||||
clearValues: () => null,
|
||||
status: FETCH_STATUS.SUCCESS,
|
||||
});
|
||||
|
||||
jest.spyOn(hook, 'useAnomalyDetectionJobsFetcher').mockReturnValue({
|
||||
anomalyDetectionJobsStatus: FETCH_STATUS.SUCCESS,
|
||||
anomalyDetectionJobsData: { jobs: [], hasLegacyJobs: false },
|
||||
|
|
|
@ -7,19 +7,17 @@
|
|||
|
||||
import {
|
||||
EuiFlexGrid,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPage,
|
||||
EuiPanel,
|
||||
EuiSpacer,
|
||||
EuiFlexGroup,
|
||||
} from '@elastic/eui';
|
||||
import React, { useMemo } from 'react';
|
||||
import React from 'react';
|
||||
import { ChartPointerEventContextProvider } from '../../../context/chart_pointer_event/chart_pointer_event_context';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { useServiceMetricChartsFetcher } from '../../../hooks/use_service_metric_charts_fetcher';
|
||||
import { MetricsChart } from '../../shared/charts/metrics_chart';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { ChartPointerEventContextProvider } from '../../../context/chart_pointer_event/chart_pointer_event_context';
|
||||
import { Projection } from '../../../../common/projections';
|
||||
import { LocalUIFilters } from '../../shared/LocalUIFilters';
|
||||
import { SearchBar } from '../../shared/search_bar';
|
||||
|
||||
interface ServiceMetricsProps {
|
||||
|
@ -37,47 +35,28 @@ export function ServiceMetrics({
|
|||
});
|
||||
const { start, end } = urlParams;
|
||||
|
||||
const localFiltersConfig: React.ComponentProps<
|
||||
typeof LocalUIFilters
|
||||
> = useMemo(
|
||||
() => ({
|
||||
filterNames: ['host', 'containerId', 'podName', 'serviceVersion'],
|
||||
params: {
|
||||
serviceName,
|
||||
},
|
||||
projection: Projection.metrics,
|
||||
showCount: false,
|
||||
}),
|
||||
[serviceName]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchBar />
|
||||
<EuiPage>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={1}>
|
||||
<LocalUIFilters {...localFiltersConfig} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={7}>
|
||||
<ChartPointerEventContextProvider>
|
||||
<EuiFlexGrid columns={2} gutterSize="s">
|
||||
{data.charts.map((chart) => (
|
||||
<EuiFlexItem key={chart.key}>
|
||||
<EuiPanel>
|
||||
<MetricsChart
|
||||
start={start}
|
||||
end={end}
|
||||
chart={chart}
|
||||
fetchStatus={status}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGrid>
|
||||
<EuiSpacer size="xxl" />
|
||||
</ChartPointerEventContextProvider>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<ChartPointerEventContextProvider>
|
||||
<EuiFlexGrid columns={2} gutterSize="s">
|
||||
{data.charts.map((chart) => (
|
||||
<EuiFlexItem key={chart.key}>
|
||||
<EuiPanel>
|
||||
<MetricsChart
|
||||
start={start}
|
||||
end={end}
|
||||
chart={chart}
|
||||
fetchStatus={status}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGrid>
|
||||
<EuiSpacer size="xxl" />
|
||||
</ChartPointerEventContextProvider>
|
||||
</EuiFlexGroup>
|
||||
</EuiPage>
|
||||
</>
|
||||
|
|
|
@ -4,30 +4,21 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPage,
|
||||
EuiPanel,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiPage, EuiPanel, EuiToolTip } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { useMemo } from 'react';
|
||||
import React 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 { useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { px, truncate, unit } from '../../../style/variables';
|
||||
import { ServiceNodeMetricOverviewLink } from '../../shared/Links/apm/ServiceNodeMetricOverviewLink';
|
||||
import { LocalUIFilters } from '../../shared/LocalUIFilters';
|
||||
import { ITableColumn, ManagedTable } from '../../shared/ManagedTable';
|
||||
import { SearchBar } from '../../shared/search_bar';
|
||||
|
||||
|
@ -47,19 +38,6 @@ function ServiceNodeOverview({ serviceName }: ServiceNodeOverviewProps) {
|
|||
const { uiFilters, urlParams } = useUrlParams();
|
||||
const { start, end } = urlParams;
|
||||
|
||||
const localFiltersConfig: React.ComponentProps<
|
||||
typeof LocalUIFilters
|
||||
> = useMemo(
|
||||
() => ({
|
||||
filterNames: ['host', 'containerId', 'podName'],
|
||||
params: {
|
||||
serviceName,
|
||||
},
|
||||
projection: Projection.serviceNodes,
|
||||
}),
|
||||
[serviceName]
|
||||
);
|
||||
|
||||
const { data: items = [] } = useFetcher(
|
||||
(callApmApi) => {
|
||||
if (!start || !end) {
|
||||
|
@ -164,27 +142,22 @@ function ServiceNodeOverview({ serviceName }: ServiceNodeOverviewProps) {
|
|||
<>
|
||||
<SearchBar />
|
||||
<EuiPage>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={1}>
|
||||
<LocalUIFilters {...localFiltersConfig} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={7}>
|
||||
<EuiPanel>
|
||||
<ManagedTable
|
||||
noItemsMessage={i18n.translate(
|
||||
'xpack.apm.jvmsTable.noJvmsLabel',
|
||||
{
|
||||
defaultMessage: 'No JVMs were found',
|
||||
}
|
||||
)}
|
||||
items={items}
|
||||
columns={columns}
|
||||
initialPageSize={INITIAL_PAGE_SIZE}
|
||||
initialSortField={INITIAL_SORT_FIELD}
|
||||
initialSortDirection={INITIAL_SORT_DIRECTION}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<EuiPanel>
|
||||
<ManagedTable
|
||||
noItemsMessage={i18n.translate(
|
||||
'xpack.apm.jvmsTable.noJvmsLabel',
|
||||
{
|
||||
defaultMessage: 'No JVMs were found',
|
||||
}
|
||||
)}
|
||||
items={items}
|
||||
columns={columns}
|
||||
initialPageSize={INITIAL_PAGE_SIZE}
|
||||
initialSortField={INITIAL_SORT_FIELD}
|
||||
initialSortDirection={INITIAL_SORT_DIRECTION}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexGroup>
|
||||
</EuiPage>
|
||||
</>
|
|
@ -6,16 +6,14 @@
|
|||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPage, EuiPanel } from '@elastic/eui';
|
||||
import React, { useMemo } from 'react';
|
||||
import React from 'react';
|
||||
import { useTrackPageview } from '../../../../../observability/public';
|
||||
import { Projection } from '../../../../common/projections';
|
||||
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { APIReturnType } from '../../../services/rest/createCallApmApi';
|
||||
import { LocalUIFilters } from '../../shared/LocalUIFilters';
|
||||
import { SearchBar } from '../../shared/search_bar';
|
||||
import { TraceList } from './TraceList';
|
||||
import { Correlations } from '../Correlations';
|
||||
import { TraceList } from './TraceList';
|
||||
|
||||
type TracesAPIResponse = APIReturnType<'GET /api/apm/traces'>;
|
||||
const DEFAULT_RESPONSE: TracesAPIResponse = {
|
||||
|
@ -48,32 +46,22 @@ export function TraceOverview() {
|
|||
useTrackPageview({ app: 'apm', path: 'traces_overview' });
|
||||
useTrackPageview({ app: 'apm', path: 'traces_overview', delay: 15000 });
|
||||
|
||||
const localUIFiltersConfig = useMemo(() => {
|
||||
const config: React.ComponentProps<typeof LocalUIFilters> = {
|
||||
filterNames: ['transactionResult', 'host', 'containerId', 'podName'],
|
||||
projection: Projection.traces,
|
||||
};
|
||||
|
||||
return config;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchBar />
|
||||
<EuiPage>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={1}>
|
||||
<Correlations />
|
||||
<LocalUIFilters {...localUIFiltersConfig} showCount={false} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={7}>
|
||||
<EuiPanel>
|
||||
<TraceList
|
||||
items={data.items}
|
||||
isLoading={status === FETCH_STATUS.LOADING}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
<Correlations />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiPanel>
|
||||
<TraceList
|
||||
items={data.items}
|
||||
isLoading={status === FETCH_STATUS.LOADING}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexGroup>
|
||||
</EuiPage>
|
||||
</>
|
|
@ -14,26 +14,23 @@ import {
|
|||
EuiSpacer,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import React, { useMemo } from 'react';
|
||||
import { isEmpty, flatten } from 'lodash';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
import { flatten, isEmpty } from 'lodash';
|
||||
import React from 'react';
|
||||
import { RouteComponentProps, useHistory } from 'react-router-dom';
|
||||
import { useTrackPageview } from '../../../../../observability/public';
|
||||
import { ChartPointerEventContextProvider } from '../../../context/chart_pointer_event/chart_pointer_event_context';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
|
||||
import { useTransactionDistributionFetcher } from '../../../hooks/use_transaction_distribution_fetcher';
|
||||
import { useWaterfallFetcher } from './use_waterfall_fetcher';
|
||||
import { ApmHeader } from '../../shared/ApmHeader';
|
||||
import { TransactionCharts } from '../../shared/charts/transaction_charts';
|
||||
import { TransactionDistribution } from './Distribution';
|
||||
import { WaterfallWithSummmary } from './WaterfallWithSummmary';
|
||||
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
|
||||
import { ChartPointerEventContextProvider } from '../../../context/chart_pointer_event/chart_pointer_event_context';
|
||||
import { useTrackPageview } from '../../../../../observability/public';
|
||||
import { Projection } from '../../../../common/projections';
|
||||
import { fromQuery, toQuery } from '../../shared/Links/url_helpers';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { LocalUIFilters } from '../../shared/LocalUIFilters';
|
||||
import { HeightRetainer } from '../../shared/HeightRetainer';
|
||||
import { Correlations } from '../Correlations';
|
||||
import { fromQuery, toQuery } from '../../shared/Links/url_helpers';
|
||||
import { SearchBar } from '../../shared/search_bar';
|
||||
import { Correlations } from '../Correlations';
|
||||
import { TransactionDistribution } from './Distribution';
|
||||
import { useWaterfallFetcher } from './use_waterfall_fetcher';
|
||||
import { WaterfallWithSummmary } from './WaterfallWithSummmary';
|
||||
|
||||
interface Sample {
|
||||
traceId: string;
|
||||
|
@ -46,7 +43,6 @@ export function TransactionDetails({
|
|||
location,
|
||||
match,
|
||||
}: TransactionDetailsProps) {
|
||||
const { serviceName } = match.params;
|
||||
const { urlParams } = useUrlParams();
|
||||
const history = useHistory();
|
||||
const {
|
||||
|
@ -59,24 +55,11 @@ export function TransactionDetails({
|
|||
exceedsMax,
|
||||
status: waterfallStatus,
|
||||
} = useWaterfallFetcher();
|
||||
const { transactionName, transactionType } = urlParams;
|
||||
const { transactionName } = urlParams;
|
||||
|
||||
useTrackPageview({ app: 'apm', path: 'transaction_details' });
|
||||
useTrackPageview({ app: 'apm', path: 'transaction_details', delay: 15000 });
|
||||
|
||||
const localUIFiltersConfig = useMemo(() => {
|
||||
const config: React.ComponentProps<typeof LocalUIFilters> = {
|
||||
filterNames: ['transactionResult', 'serviceVersion'],
|
||||
projection: Projection.transactions,
|
||||
params: {
|
||||
transactionName,
|
||||
transactionType,
|
||||
serviceName,
|
||||
},
|
||||
};
|
||||
return config;
|
||||
}, [transactionName, transactionType, serviceName]);
|
||||
|
||||
const selectedSample = flatten(
|
||||
distributionData.buckets.map((bucket) => bucket.samples)
|
||||
).find(
|
||||
|
@ -116,45 +99,45 @@ export function TransactionDetails({
|
|||
</ApmHeader>
|
||||
<SearchBar showTimeComparison />
|
||||
<EuiPage>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={1}>
|
||||
<Correlations />
|
||||
<LocalUIFilters {...localUIFiltersConfig} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={7}>
|
||||
<ChartPointerEventContextProvider>
|
||||
<TransactionCharts />
|
||||
</ChartPointerEventContextProvider>
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
<Correlations />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiHorizontalRule size="full" margin="l" />
|
||||
<ChartPointerEventContextProvider>
|
||||
<TransactionCharts />
|
||||
</ChartPointerEventContextProvider>
|
||||
|
||||
<EuiPanel>
|
||||
<TransactionDistribution
|
||||
distribution={distributionData}
|
||||
fetchStatus={distributionStatus}
|
||||
urlParams={urlParams}
|
||||
bucketIndex={bucketIndex}
|
||||
onBucketClick={(bucket) => {
|
||||
if (!isEmpty(bucket.samples)) {
|
||||
selectSampleFromBucketClick(bucket.samples[0]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiPanel>
|
||||
<EuiHorizontalRule size="full" margin="l" />
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
<EuiPanel>
|
||||
<TransactionDistribution
|
||||
distribution={distributionData}
|
||||
fetchStatus={distributionStatus}
|
||||
urlParams={urlParams}
|
||||
bucketIndex={bucketIndex}
|
||||
onBucketClick={(bucket) => {
|
||||
if (!isEmpty(bucket.samples)) {
|
||||
selectSampleFromBucketClick(bucket.samples[0]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiPanel>
|
||||
|
||||
<HeightRetainer>
|
||||
<WaterfallWithSummmary
|
||||
location={location}
|
||||
urlParams={urlParams}
|
||||
waterfall={waterfall}
|
||||
isLoading={waterfallStatus === FETCH_STATUS.LOADING}
|
||||
exceedsMax={exceedsMax}
|
||||
traceSamples={traceSamples}
|
||||
/>
|
||||
</HeightRetainer>
|
||||
</EuiFlexItem>
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<HeightRetainer>
|
||||
<WaterfallWithSummmary
|
||||
location={location}
|
||||
urlParams={urlParams}
|
||||
waterfall={waterfall}
|
||||
isLoading={waterfallStatus === FETCH_STATUS.LOADING}
|
||||
exceedsMax={exceedsMax}
|
||||
traceSamples={traceSamples}
|
||||
/>
|
||||
</HeightRetainer>
|
||||
</EuiFlexGroup>
|
||||
</EuiPage>
|
||||
</>
|
|
@ -10,7 +10,6 @@ import {
|
|||
EuiCode,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiHorizontalRule,
|
||||
EuiPage,
|
||||
EuiPanel,
|
||||
EuiSpacer,
|
||||
|
@ -19,25 +18,23 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { Location } from 'history';
|
||||
import React, { useMemo } from 'react';
|
||||
import React 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 { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context';
|
||||
import { IUrlParams } from '../../../context/url_params_context/types';
|
||||
import { useTransactionListFetcher } from './use_transaction_list';
|
||||
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
|
||||
import { TransactionCharts } from '../../shared/charts/transaction_charts';
|
||||
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 { TransactionTypeSelect } from '../../shared/transaction_type_select';
|
||||
import { Correlations } from '../Correlations';
|
||||
import { TransactionList } from './TransactionList';
|
||||
import { useRedirect } from './useRedirect';
|
||||
import { UserExperienceCallout } from './user_experience_callout';
|
||||
import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context';
|
||||
import { useTransactionListFetcher } from './use_transaction_list';
|
||||
|
||||
function getRedirectLocation({
|
||||
location,
|
||||
|
@ -68,7 +65,7 @@ interface TransactionOverviewProps {
|
|||
export function TransactionOverview({ serviceName }: TransactionOverviewProps) {
|
||||
const location = useLocation();
|
||||
const { urlParams } = useUrlParams();
|
||||
const { transactionType, transactionTypes } = useApmServiceContext();
|
||||
const { transactionType } = useApmServiceContext();
|
||||
|
||||
// redirect to first transaction type
|
||||
useRedirect(getRedirectLocation({ location, transactionType, urlParams }));
|
||||
|
@ -80,27 +77,6 @@ export function TransactionOverview({ serviceName }: TransactionOverviewProps) {
|
|||
transactionListStatus,
|
||||
} = useTransactionListFetcher();
|
||||
|
||||
const localFiltersConfig: React.ComponentProps<
|
||||
typeof LocalUIFilters
|
||||
> = useMemo(
|
||||
() => ({
|
||||
shouldFetch: !!transactionType,
|
||||
filterNames: [
|
||||
'transactionResult',
|
||||
'host',
|
||||
'containerId',
|
||||
'podName',
|
||||
'serviceVersion',
|
||||
],
|
||||
params: {
|
||||
serviceName,
|
||||
transactionType,
|
||||
},
|
||||
projection: Projection.transactionGroups,
|
||||
}),
|
||||
[serviceName, transactionType]
|
||||
);
|
||||
|
||||
// TODO: improve urlParams typings.
|
||||
// `serviceName` or `transactionType` will never be undefined here, and this check should not be needed
|
||||
if (!serviceName) {
|
||||
|
@ -112,74 +88,92 @@ export function TransactionOverview({ serviceName }: TransactionOverviewProps) {
|
|||
<SearchBar showTimeComparison />
|
||||
|
||||
<EuiPage>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={1}>
|
||||
<Correlations />
|
||||
<LocalUIFilters {...localFiltersConfig}>
|
||||
<TransactionTypeFilter transactionTypes={transactionTypes} />
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup justifyContent="spaceBetween">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="s"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="s">
|
||||
<h2>
|
||||
{i18n.translate('xpack.apm.transactionOverviewTitle', {
|
||||
defaultMessage: 'Transactions',
|
||||
})}
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={2}>
|
||||
<TransactionTypeSelect />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiHorizontalRule margin="none" />
|
||||
</LocalUIFilters>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={7}>
|
||||
{transactionType === TRANSACTION_PAGE_LOAD && (
|
||||
<>
|
||||
<UserExperienceCallout serviceName={serviceName} />
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
)}
|
||||
<TransactionCharts />
|
||||
<EuiSpacer size="s" />
|
||||
<EuiPanel>
|
||||
<EuiTitle size="xs">
|
||||
<h3>Transactions</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
{!transactionListData.isAggregationAccurate && (
|
||||
<EuiCallOut
|
||||
title={i18n.translate(
|
||||
'xpack.apm.transactionCardinalityWarning.title',
|
||||
{
|
||||
defaultMessage:
|
||||
'This view shows a subset of reported transactions.',
|
||||
}
|
||||
)}
|
||||
color="danger"
|
||||
iconType="alert"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.apm.transactionCardinalityWarning.body"
|
||||
defaultMessage="The number of unique transaction names exceeds the configured value of {bucketSize}. Try reconfiguring your agents to group similar transactions or increase the value of {codeBlock}"
|
||||
values={{
|
||||
bucketSize: transactionListData.bucketSize,
|
||||
codeBlock: (
|
||||
<EuiCode>
|
||||
xpack.apm.ui.transactionGroupBucketSize
|
||||
</EuiCode>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<Correlations />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<ElasticDocsLink
|
||||
section="/kibana"
|
||||
path="/troubleshooting.html#troubleshooting-too-many-transactions"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.apm.transactionCardinalityWarning.docsLink',
|
||||
{ defaultMessage: 'Learn more in the docs' }
|
||||
)}
|
||||
</ElasticDocsLink>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
)}
|
||||
{transactionType === TRANSACTION_PAGE_LOAD && (
|
||||
<>
|
||||
<UserExperienceCallout serviceName={serviceName} />
|
||||
<EuiSpacer size="s" />
|
||||
<TransactionList
|
||||
isLoading={transactionListStatus === 'loading'}
|
||||
items={transactionListData.items || []}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</>
|
||||
)}
|
||||
<TransactionCharts />
|
||||
<EuiSpacer size="s" />
|
||||
<EuiPanel>
|
||||
<EuiTitle size="xs">
|
||||
<h3>Transactions</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
{!transactionListData.isAggregationAccurate && (
|
||||
<EuiCallOut
|
||||
title={i18n.translate(
|
||||
'xpack.apm.transactionCardinalityWarning.title',
|
||||
{
|
||||
defaultMessage:
|
||||
'This view shows a subset of reported transactions.',
|
||||
}
|
||||
)}
|
||||
color="danger"
|
||||
iconType="alert"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.apm.transactionCardinalityWarning.body"
|
||||
defaultMessage="The number of unique transaction names exceeds the configured value of {bucketSize}. Try reconfiguring your agents to group similar transactions or increase the value of {codeBlock}"
|
||||
values={{
|
||||
bucketSize: transactionListData.bucketSize,
|
||||
codeBlock: (
|
||||
<EuiCode>
|
||||
xpack.apm.ui.transactionGroupBucketSize
|
||||
</EuiCode>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<ElasticDocsLink
|
||||
section="/kibana"
|
||||
path="/troubleshooting.html#troubleshooting-too-many-transactions"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.apm.transactionCardinalityWarning.docsLink',
|
||||
{ defaultMessage: 'Learn more in the docs' }
|
||||
)}
|
||||
</ElasticDocsLink>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
)}
|
||||
<EuiSpacer size="s" />
|
||||
<TransactionList
|
||||
isLoading={transactionListStatus === 'loading'}
|
||||
items={transactionListData.items || []}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexGroup>
|
||||
</EuiPage>
|
||||
</>
|
||||
|
|
|
@ -136,7 +136,9 @@ describe('TransactionOverview', () => {
|
|||
expect(getByText(container, 'firstType')).toBeInTheDocument();
|
||||
expect(getByText(container, 'secondType')).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(getByText(container, 'firstType'));
|
||||
fireEvent.change(getByText(container, 'firstType').parentElement!, {
|
||||
target: { value: 'firstType' },
|
||||
});
|
||||
|
||||
expect(history.push).toHaveBeenCalled();
|
||||
expect(history.location.search).toEqual(
|
||||
|
|
|
@ -1,65 +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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiHorizontalRule,
|
||||
EuiRadioGroup,
|
||||
EuiSpacer,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
|
||||
import { fromQuery, toQuery } from '../../Links/url_helpers';
|
||||
|
||||
interface Props {
|
||||
transactionTypes: string[];
|
||||
}
|
||||
|
||||
function TransactionTypeFilter({ transactionTypes }: Props) {
|
||||
const history = useHistory();
|
||||
const {
|
||||
urlParams: { transactionType },
|
||||
} = useUrlParams();
|
||||
|
||||
const options = transactionTypes.map((type) => ({
|
||||
id: type,
|
||||
label: type,
|
||||
}));
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiTitle size="xxxs" textTransform="uppercase">
|
||||
<h4>
|
||||
{i18n.translate('xpack.apm.localFilters.titles.transactionType', {
|
||||
defaultMessage: 'Transaction type',
|
||||
})}
|
||||
</h4>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiHorizontalRule margin="none" />
|
||||
<EuiSpacer size="s" />
|
||||
<EuiRadioGroup
|
||||
options={options}
|
||||
idSelected={transactionType}
|
||||
onChange={(selectedTransactionType) => {
|
||||
const newLocation = {
|
||||
...history.location,
|
||||
search: fromQuery({
|
||||
...toQuery(history.location.search),
|
||||
transactionType: selectedTransactionType,
|
||||
}),
|
||||
};
|
||||
history.push(newLocation);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export { TransactionTypeFilter };
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiToolTip, EuiText } from '@elastic/eui';
|
||||
import { asDuration } from '../../../../common/utils/formatters';
|
||||
import { PercentOfParent } from '../../app/TransactionDetails/WaterfallWithSummmary/PercentOfParent';
|
||||
import { PercentOfParent } from '../../app/transaction_details/WaterfallWithSummmary/PercentOfParent';
|
||||
|
||||
interface Props {
|
||||
duration: number;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { AgentMarker } from './AgentMarker';
|
||||
import { AgentMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
import { AgentMark } from '../../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
import { EuiThemeProvider } from '../../../../../../../../../src/plugins/kibana_react/common';
|
||||
|
||||
describe('AgentMarker', () => {
|
||||
|
|
|
@ -12,7 +12,7 @@ import { asDuration } from '../../../../../../common/utils/formatters';
|
|||
import { useTheme } from '../../../../../hooks/use_theme';
|
||||
import { px, units } from '../../../../../style/variables';
|
||||
import { Legend } from '../../Legend';
|
||||
import { AgentMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
import { AgentMark } from '../../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
|
||||
const NameContainer = styled.div`
|
||||
border-bottom: 1px solid ${({ theme }) => theme.eui.euiColorMediumShade};
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
expectTextsInDocument,
|
||||
renderWithTheme,
|
||||
} from '../../../../../utils/testHelpers';
|
||||
import { ErrorMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
import { ErrorMark } from '../../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
import { ErrorMarker } from './ErrorMarker';
|
||||
|
||||
function Wrapper({ children }: { children?: ReactNode }) {
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
} from '../../../../../../common/elasticsearch_fieldnames';
|
||||
import { useUrlParams } from '../../../../../context/url_params_context/use_url_params';
|
||||
import { px, unit, units } from '../../../../../style/variables';
|
||||
import { ErrorMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
import { ErrorMark } from '../../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
import { ErrorDetailLink } from '../../../Links/apm/ErrorDetailLink';
|
||||
import { Legend, Shape } from '../../Legend';
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { Marker } from './';
|
||||
import { AgentMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
import { ErrorMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
import { AgentMark } from '../../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
import { ErrorMark } from '../../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
|
||||
describe('Marker', () => {
|
||||
it('renders agent marker', () => {
|
||||
|
|
|
@ -10,8 +10,8 @@ import styled from 'styled-components';
|
|||
import { px } from '../../../../../style/variables';
|
||||
import { AgentMarker } from './AgentMarker';
|
||||
import { ErrorMarker } from './ErrorMarker';
|
||||
import { AgentMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
import { ErrorMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
import { AgentMark } from '../../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
import { ErrorMark } from '../../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
|
||||
interface Props {
|
||||
mark: ErrorMark | AgentMark;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React from 'react';
|
||||
import { VerticalGridLines, XYPlot } from 'react-vis';
|
||||
import { useTheme } from '../../../../hooks/use_theme';
|
||||
import { Mark } from '../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks';
|
||||
import { Mark } from '../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks';
|
||||
import { PlotValues } from './plotUtils';
|
||||
|
||||
interface VerticalLinesProps {
|
||||
|
|
|
@ -11,8 +11,8 @@ import { makeWidthFlexible } from 'react-vis';
|
|||
import { getPlotValues } from './plotUtils';
|
||||
import { TimelineAxis } from './TimelineAxis';
|
||||
import { VerticalLines } from './VerticalLines';
|
||||
import { ErrorMark } from '../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
import { AgentMark } from '../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
import { ErrorMark } from '../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks';
|
||||
import { AgentMark } from '../../../app/transaction_details/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks';
|
||||
|
||||
export type Mark = AgentMark | ErrorMark;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import { useBreakPoints } from '../../hooks/use_break_points';
|
|||
|
||||
const SearchBarFlexGroup = styled(EuiFlexGroup)`
|
||||
margin: ${({ theme }) =>
|
||||
`${theme.eui.euiSizeM} ${theme.eui.euiSizeM} -${theme.eui.gutterTypes.gutterMedium} ${theme.eui.euiSizeM}`};
|
||||
`${theme.eui.euiSizeS} ${theme.eui.euiSizeS} -${theme.eui.gutterTypes.gutterMedium} ${theme.eui.euiSizeS}`};
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiSelect } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { FormEvent, useCallback } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
import { useApmServiceContext } from '../../context/apm_service/use_apm_service_context';
|
||||
import { useUrlParams } from '../../context/url_params_context/use_url_params';
|
||||
import * as urlHelpers from './Links/url_helpers';
|
||||
|
||||
// The default transaction type (for non-RUM services) is "request". Set the
|
||||
// min-width on here to the width when "request" is loaded so it doesn't start
|
||||
// out collapsed and change its width when the list of transaction types is loaded.
|
||||
const EuiSelectWithWidth = styled(EuiSelect)`
|
||||
min-width: 157px;
|
||||
`;
|
||||
|
||||
export function TransactionTypeSelect() {
|
||||
const { transactionTypes } = useApmServiceContext();
|
||||
const history = useHistory();
|
||||
const {
|
||||
urlParams: { transactionType },
|
||||
} = useUrlParams();
|
||||
|
||||
const handleChange = useCallback(
|
||||
(event: FormEvent<HTMLSelectElement>) => {
|
||||
const selectedTransactionType = event.currentTarget.value;
|
||||
urlHelpers.push(history, {
|
||||
query: { transactionType: selectedTransactionType },
|
||||
});
|
||||
},
|
||||
[history]
|
||||
);
|
||||
|
||||
const options = transactionTypes.map((t) => ({ text: t, value: t }));
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiSelectWithWidth
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
prepend={i18n.translate('xpack.apm.transactionTypeSelectLabel', {
|
||||
defaultMessage: 'Type',
|
||||
})}
|
||||
value={transactionType}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -66,15 +66,8 @@ import {
|
|||
transactionThroughputChatsRoute,
|
||||
} from './transactions';
|
||||
import {
|
||||
errorGroupsLocalFiltersRoute,
|
||||
metricsLocalFiltersRoute,
|
||||
servicesLocalFiltersRoute,
|
||||
tracesLocalFiltersRoute,
|
||||
transactionGroupsLocalFiltersRoute,
|
||||
transactionsLocalFiltersRoute,
|
||||
serviceNodesLocalFiltersRoute,
|
||||
uiFiltersEnvironmentsRoute,
|
||||
rumOverviewLocalFiltersRoute,
|
||||
uiFiltersEnvironmentsRoute,
|
||||
} from './ui_filters';
|
||||
import { serviceMapRoute, serviceMapServiceNodeRoute } from './service_map';
|
||||
import {
|
||||
|
@ -176,13 +169,6 @@ const createApmApi = () => {
|
|||
.add(transactionThroughputChatsRoute)
|
||||
|
||||
// UI filters
|
||||
.add(errorGroupsLocalFiltersRoute)
|
||||
.add(metricsLocalFiltersRoute)
|
||||
.add(servicesLocalFiltersRoute)
|
||||
.add(tracesLocalFiltersRoute)
|
||||
.add(transactionGroupsLocalFiltersRoute)
|
||||
.add(transactionsLocalFiltersRoute)
|
||||
.add(serviceNodesLocalFiltersRoute)
|
||||
.add(uiFiltersEnvironmentsRoute)
|
||||
|
||||
// Service map
|
||||
|
|
|
@ -7,29 +7,23 @@
|
|||
|
||||
import * as t from 'io-ts';
|
||||
import { omit } from 'lodash';
|
||||
import { jsonRt } from '../../common/runtime_types/json_rt';
|
||||
import { LocalUIFilterName } from '../../common/ui_filter';
|
||||
import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions';
|
||||
import { getEsFilter } from '../lib/helpers/convert_ui_filters/get_es_filter';
|
||||
import {
|
||||
setupRequest,
|
||||
Setup,
|
||||
setupRequest,
|
||||
SetupTimeRange,
|
||||
} from '../lib/helpers/setup_request';
|
||||
import { getEnvironments } from '../lib/ui_filters/get_environments';
|
||||
import { Projection } from '../projections/typings';
|
||||
import { localUIFilterNames } from '../lib/ui_filters/local_ui_filters/config';
|
||||
import { getEsFilter } from '../lib/helpers/convert_ui_filters/get_es_filter';
|
||||
import { getLocalUIFilters } from '../lib/ui_filters/local_ui_filters';
|
||||
import { getServicesProjection } from '../projections/services';
|
||||
import { getTransactionGroupsProjection } from '../projections/transaction_groups';
|
||||
import { getMetricsProjection } from '../projections/metrics';
|
||||
import { getErrorGroupsProjection } from '../projections/errors';
|
||||
import { getTransactionsProjection } from '../projections/transactions';
|
||||
import { createRoute } from './create_route';
|
||||
import { uiFiltersRt, rangeRt } from './default_api_types';
|
||||
import { jsonRt } from '../../common/runtime_types/json_rt';
|
||||
import { getServiceNodesProjection } from '../projections/service_nodes';
|
||||
import { localUIFilterNames } from '../lib/ui_filters/local_ui_filters/config';
|
||||
import { getRumPageLoadTransactionsProjection } from '../projections/rum_page_load_transactions';
|
||||
import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions';
|
||||
import { Projection } from '../projections/typings';
|
||||
import { createRoute } from './create_route';
|
||||
import { rangeRt, uiFiltersRt } from './default_api_types';
|
||||
import { APMRequestHandlerContext } from './typings';
|
||||
import { LocalUIFilterName } from '../../common/ui_filter';
|
||||
|
||||
export const uiFiltersEnvironmentsRoute = createRoute({
|
||||
endpoint: 'GET /api/apm/ui_filters/environments',
|
||||
|
@ -122,136 +116,6 @@ function createLocalFiltersRoute<
|
|||
});
|
||||
}
|
||||
|
||||
export const servicesLocalFiltersRoute = createLocalFiltersRoute({
|
||||
endpoint: `GET /api/apm/ui_filters/local_filters/services`,
|
||||
getProjection: async ({ context, setup }) => {
|
||||
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
||||
setup
|
||||
);
|
||||
|
||||
return getServicesProjection({ setup, searchAggregatedTransactions });
|
||||
},
|
||||
queryRt: t.type({}),
|
||||
});
|
||||
|
||||
export const transactionGroupsLocalFiltersRoute = createLocalFiltersRoute({
|
||||
endpoint: 'GET /api/apm/ui_filters/local_filters/transactionGroups',
|
||||
getProjection: async ({ context, setup, query }) => {
|
||||
const { transactionType, serviceName, transactionName } = query;
|
||||
|
||||
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
||||
setup
|
||||
);
|
||||
|
||||
return getTransactionGroupsProjection({
|
||||
setup,
|
||||
options: {
|
||||
type: 'top_transactions',
|
||||
transactionType,
|
||||
serviceName,
|
||||
transactionName,
|
||||
searchAggregatedTransactions,
|
||||
},
|
||||
});
|
||||
},
|
||||
queryRt: t.intersection([
|
||||
t.type({
|
||||
serviceName: t.string,
|
||||
transactionType: t.string,
|
||||
}),
|
||||
t.partial({
|
||||
transactionName: t.string,
|
||||
}),
|
||||
]),
|
||||
});
|
||||
|
||||
export const tracesLocalFiltersRoute = createLocalFiltersRoute({
|
||||
endpoint: 'GET /api/apm/ui_filters/local_filters/traces',
|
||||
getProjection: async ({ setup, context }) => {
|
||||
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
||||
setup
|
||||
);
|
||||
|
||||
return getTransactionGroupsProjection({
|
||||
setup,
|
||||
options: { type: 'top_traces', searchAggregatedTransactions },
|
||||
});
|
||||
},
|
||||
queryRt: t.type({}),
|
||||
});
|
||||
|
||||
export const transactionsLocalFiltersRoute = createLocalFiltersRoute({
|
||||
endpoint: 'GET /api/apm/ui_filters/local_filters/transactions',
|
||||
getProjection: async ({ context, setup, query }) => {
|
||||
const { transactionType, serviceName, transactionName } = query;
|
||||
|
||||
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
||||
setup
|
||||
);
|
||||
|
||||
return getTransactionsProjection({
|
||||
setup,
|
||||
transactionType,
|
||||
serviceName,
|
||||
transactionName,
|
||||
searchAggregatedTransactions,
|
||||
});
|
||||
},
|
||||
queryRt: t.type({
|
||||
transactionType: t.string,
|
||||
transactionName: t.string,
|
||||
serviceName: t.string,
|
||||
}),
|
||||
});
|
||||
|
||||
export const metricsLocalFiltersRoute = createLocalFiltersRoute({
|
||||
endpoint: 'GET /api/apm/ui_filters/local_filters/metrics',
|
||||
getProjection: ({ setup, query }) => {
|
||||
const { serviceName, serviceNodeName } = query;
|
||||
return getMetricsProjection({
|
||||
setup,
|
||||
serviceName,
|
||||
serviceNodeName,
|
||||
});
|
||||
},
|
||||
queryRt: t.intersection([
|
||||
t.type({
|
||||
serviceName: t.string,
|
||||
}),
|
||||
t.partial({
|
||||
serviceNodeName: t.string,
|
||||
}),
|
||||
]),
|
||||
});
|
||||
|
||||
export const errorGroupsLocalFiltersRoute = createLocalFiltersRoute({
|
||||
endpoint: 'GET /api/apm/ui_filters/local_filters/errorGroups',
|
||||
getProjection: ({ setup, query }) => {
|
||||
const { serviceName } = query;
|
||||
return getErrorGroupsProjection({
|
||||
setup,
|
||||
serviceName,
|
||||
});
|
||||
},
|
||||
queryRt: t.type({
|
||||
serviceName: t.string,
|
||||
}),
|
||||
});
|
||||
|
||||
export const serviceNodesLocalFiltersRoute = createLocalFiltersRoute({
|
||||
endpoint: 'GET /api/apm/ui_filters/local_filters/serviceNodes',
|
||||
getProjection: ({ setup, query }) => {
|
||||
const { serviceName } = query;
|
||||
return getServiceNodesProjection({
|
||||
setup,
|
||||
serviceName,
|
||||
});
|
||||
},
|
||||
queryRt: t.type({
|
||||
serviceName: t.string,
|
||||
}),
|
||||
});
|
||||
|
||||
export const rumOverviewLocalFiltersRoute = createLocalFiltersRoute({
|
||||
endpoint: 'GET /api/apm/ui_filters/local_filters/rumOverview',
|
||||
getProjection: async ({ setup }) => {
|
||||
|
|
|
@ -5104,7 +5104,6 @@
|
|||
"xpack.apm.localFilters.titles.serviceName": "サービス名",
|
||||
"xpack.apm.localFilters.titles.serviceVersion": "サービスバージョン",
|
||||
"xpack.apm.localFilters.titles.transactionResult": "トランザクション結果",
|
||||
"xpack.apm.localFilters.titles.transactionType": "トランザクションタイプ",
|
||||
"xpack.apm.localFilters.titles.transactionUrl": "Url",
|
||||
"xpack.apm.localFiltersTitle": "フィルター",
|
||||
"xpack.apm.metadataTable.section.agentLabel": "エージェント",
|
||||
|
|
|
@ -5112,7 +5112,6 @@
|
|||
"xpack.apm.localFilters.titles.serviceName": "服务名称",
|
||||
"xpack.apm.localFilters.titles.serviceVersion": "服务版本",
|
||||
"xpack.apm.localFilters.titles.transactionResult": "事务结果",
|
||||
"xpack.apm.localFilters.titles.transactionType": "事务类型",
|
||||
"xpack.apm.localFilters.titles.transactionUrl": "URL",
|
||||
"xpack.apm.localFiltersTitle": "筛选",
|
||||
"xpack.apm.metadataTable.section.agentLabel": "代理",
|
||||
|
|
Loading…
Reference in a new issue