mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[APM] Mobile most used pie charts with Lens (#144232)
* WIP * Fix eslint * split code * Add unit tests * respect search bar filter * Fix i18n id * Add open in Lens action * Clean up attributes * Organise react components * Move most used chart to service overview * Remove kuery from filters * Pass mobile filters to Lens * Use same ES fields as mobile filters * Fix tests * Clean up code * Fix i18n * Use i18n for lens labels * Address PR comments
This commit is contained in:
parent
404d08f600
commit
14e4ab4367
12 changed files with 532 additions and 11 deletions
|
@ -45,7 +45,7 @@ exports[`Error CONTAINER_IMAGE 1`] = `undefined`;
|
|||
|
||||
exports[`Error DESTINATION_ADDRESS 1`] = `undefined`;
|
||||
|
||||
exports[`Error DEVICE_MODEL_IDENTIFIER 1`] = `undefined`;
|
||||
exports[`Error DEVICE_MODEL_NAME 1`] = `undefined`;
|
||||
|
||||
exports[`Error ERROR_CULPRIT 1`] = `"handleOopsie"`;
|
||||
|
||||
|
@ -310,7 +310,7 @@ exports[`Span CONTAINER_IMAGE 1`] = `undefined`;
|
|||
|
||||
exports[`Span DESTINATION_ADDRESS 1`] = `undefined`;
|
||||
|
||||
exports[`Span DEVICE_MODEL_IDENTIFIER 1`] = `undefined`;
|
||||
exports[`Span DEVICE_MODEL_NAME 1`] = `undefined`;
|
||||
|
||||
exports[`Span ERROR_CULPRIT 1`] = `undefined`;
|
||||
|
||||
|
@ -571,7 +571,7 @@ exports[`Transaction CONTAINER_IMAGE 1`] = `undefined`;
|
|||
|
||||
exports[`Transaction DESTINATION_ADDRESS 1`] = `undefined`;
|
||||
|
||||
exports[`Transaction DEVICE_MODEL_IDENTIFIER 1`] = `undefined`;
|
||||
exports[`Transaction DEVICE_MODEL_NAME 1`] = `undefined`;
|
||||
|
||||
exports[`Transaction ERROR_CULPRIT 1`] = `undefined`;
|
||||
|
||||
|
|
|
@ -161,5 +161,5 @@ export const TIER = '_tier';
|
|||
export const INDEX = '_index';
|
||||
|
||||
// Mobile
|
||||
export const DEVICE_MODEL_IDENTIFIER = 'device.model.identifier';
|
||||
export const NETWORK_CONNECTION_TYPE = 'network.connection.type';
|
||||
export const DEVICE_MODEL_NAME = 'device.model.name';
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"unifiedSearch",
|
||||
"dataViews",
|
||||
"advancedSettings",
|
||||
"lens",
|
||||
"maps"
|
||||
],
|
||||
"optionalPlugins": [
|
||||
|
@ -51,4 +52,4 @@
|
|||
"esUiShared",
|
||||
"maps"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ export const renderApp = ({
|
|||
observabilityRuleTypeRegistry,
|
||||
dataViews: pluginsStart.dataViews,
|
||||
unifiedSearch: pluginsStart.unifiedSearch,
|
||||
lens: pluginsStart.lens,
|
||||
};
|
||||
|
||||
// render APM feedback link in global help menu
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Most used chart with Lens gets lens attributes 1`] = `
|
||||
Object {
|
||||
"references": Array [
|
||||
Object {
|
||||
"id": "apm_static_index_pattern_id",
|
||||
"name": "indexpattern-datasource-layer-host-os-version",
|
||||
"type": "index-pattern",
|
||||
},
|
||||
],
|
||||
"state": Object {
|
||||
"datasourceStates": Object {
|
||||
"formBased": Object {
|
||||
"layers": Object {
|
||||
"host-os-version": Object {
|
||||
"columnOrder": Array [
|
||||
"termsColumn",
|
||||
"countColumn",
|
||||
],
|
||||
"columns": Object {
|
||||
"countColumn": Object {
|
||||
"dataType": "number",
|
||||
"isBucketed": false,
|
||||
"label": "Count of records",
|
||||
"operationType": "count",
|
||||
"scale": "ratio",
|
||||
"sourceField": "___records___",
|
||||
},
|
||||
"termsColumn": Object {
|
||||
"dataType": "string",
|
||||
"isBucketed": true,
|
||||
"label": "Top 5 values of host.os.version",
|
||||
"operationType": "terms",
|
||||
"params": Object {
|
||||
"orderBy": Object {
|
||||
"columnId": "countColumn",
|
||||
"type": "column",
|
||||
},
|
||||
"orderDirection": "desc",
|
||||
"size": 5,
|
||||
},
|
||||
"scale": "ordinal",
|
||||
"sourceField": "host.os.version",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"filters": Array [
|
||||
Object {
|
||||
"meta": Object {},
|
||||
"query": Object {
|
||||
"term": Object {
|
||||
"processor.event": "transaction",
|
||||
},
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"meta": Object {},
|
||||
"query": Object {
|
||||
"term": Object {
|
||||
"service.name": "opbeans-swift",
|
||||
},
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"meta": Object {},
|
||||
"query": Object {
|
||||
"term": Object {
|
||||
"transaction.type": "request",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
"query": Object {
|
||||
"language": "kuery",
|
||||
"query": "",
|
||||
},
|
||||
"visualization": Object {
|
||||
"layers": Array [
|
||||
Object {
|
||||
"categoryDisplay": "default",
|
||||
"layerId": "host-os-version",
|
||||
"layerType": "data",
|
||||
"legendDisplay": "hide",
|
||||
"metric": "countColumn",
|
||||
"numberDisplay": "percent",
|
||||
"primaryGroups": Array [
|
||||
"termsColumn",
|
||||
],
|
||||
},
|
||||
],
|
||||
"shape": "pie",
|
||||
},
|
||||
},
|
||||
"title": "most-used-host-os-version",
|
||||
"visualizationType": "lnsPie",
|
||||
}
|
||||
`;
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
CountIndexPatternColumn,
|
||||
TermsIndexPatternColumn,
|
||||
PersistedIndexPatternLayer,
|
||||
PieVisualizationState,
|
||||
TypedLensByValueInput,
|
||||
} from '@kbn/lens-plugin/public';
|
||||
import type { Filter } from '@kbn/es-query';
|
||||
import { APM_STATIC_DATA_VIEW_ID } from '../../../../../../common/data_view_constants';
|
||||
import { MostUsedMetricTypes } from '.';
|
||||
|
||||
const BUCKET_SIZE = 5;
|
||||
|
||||
export function getLensAttributes({
|
||||
metric,
|
||||
filters,
|
||||
kuery = '',
|
||||
}: {
|
||||
metric: MostUsedMetricTypes;
|
||||
filters: Filter[];
|
||||
kuery?: string;
|
||||
}): TypedLensByValueInput['attributes'] {
|
||||
const metricId = metric.replaceAll('.', '-');
|
||||
|
||||
const columnA = 'termsColumn';
|
||||
const columnB = 'countColumn';
|
||||
|
||||
const dataLayer: PersistedIndexPatternLayer = {
|
||||
columnOrder: [columnA, columnB],
|
||||
columns: {
|
||||
[columnA]: {
|
||||
label: i18n.translate(
|
||||
'xpack.apm.serviceOverview.lensFlyout.topValues',
|
||||
{
|
||||
defaultMessage: 'Top {BUCKET_SIZE} values of {metric}',
|
||||
values: {
|
||||
BUCKET_SIZE,
|
||||
metric,
|
||||
},
|
||||
}
|
||||
),
|
||||
dataType: 'string',
|
||||
operationType: 'terms',
|
||||
scale: 'ordinal',
|
||||
sourceField: metric,
|
||||
isBucketed: true,
|
||||
params: {
|
||||
size: BUCKET_SIZE,
|
||||
orderBy: {
|
||||
type: 'column',
|
||||
columnId: columnB,
|
||||
},
|
||||
orderDirection: 'desc',
|
||||
},
|
||||
} as TermsIndexPatternColumn,
|
||||
[columnB]: {
|
||||
label: i18n.translate(
|
||||
'xpack.apm.serviceOverview.lensFlyout.countRecords',
|
||||
{
|
||||
defaultMessage: 'Count of records',
|
||||
}
|
||||
),
|
||||
dataType: 'number',
|
||||
operationType: 'count',
|
||||
scale: 'ratio',
|
||||
isBucketed: false,
|
||||
sourceField: '___records___',
|
||||
} as CountIndexPatternColumn,
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
title: `most-used-${metricId}`,
|
||||
visualizationType: 'lnsPie',
|
||||
references: [
|
||||
{
|
||||
type: 'index-pattern',
|
||||
id: APM_STATIC_DATA_VIEW_ID,
|
||||
name: `indexpattern-datasource-layer-${metricId}`,
|
||||
},
|
||||
],
|
||||
state: {
|
||||
visualization: {
|
||||
shape: 'pie',
|
||||
layers: [
|
||||
{
|
||||
layerId: metricId,
|
||||
primaryGroups: [columnA],
|
||||
metric: columnB,
|
||||
categoryDisplay: 'default',
|
||||
legendDisplay: 'hide',
|
||||
numberDisplay: 'percent',
|
||||
layerType: 'data',
|
||||
},
|
||||
],
|
||||
} as PieVisualizationState,
|
||||
datasourceStates: {
|
||||
formBased: {
|
||||
layers: {
|
||||
[metricId]: dataLayer,
|
||||
},
|
||||
},
|
||||
},
|
||||
filters,
|
||||
query: { language: 'kuery', query: kuery },
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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 { EuiTitle, EuiFlexItem, EuiPanel } from '@elastic/eui';
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import type { Filter } from '@kbn/es-query';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ViewMode } from '@kbn/embeddable-plugin/public';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { ApmPluginStartDeps } from '../../../../../plugin';
|
||||
import { getLensAttributes } from './get_lens_attributes';
|
||||
import {
|
||||
DEVICE_MODEL_NAME,
|
||||
HOST_OS_VERSION,
|
||||
NETWORK_CONNECTION_TYPE,
|
||||
SERVICE_VERSION,
|
||||
} from '../../../../../../common/elasticsearch_fieldnames';
|
||||
|
||||
export type MostUsedMetricTypes =
|
||||
| typeof DEVICE_MODEL_NAME
|
||||
| typeof SERVICE_VERSION
|
||||
| typeof HOST_OS_VERSION
|
||||
| typeof NETWORK_CONNECTION_TYPE;
|
||||
|
||||
export function MostUsedChart({
|
||||
title,
|
||||
start,
|
||||
end,
|
||||
kuery,
|
||||
filters,
|
||||
metric,
|
||||
}: {
|
||||
title: React.ReactNode;
|
||||
start: string;
|
||||
end: string;
|
||||
kuery?: string;
|
||||
filters: Filter[];
|
||||
metric: MostUsedMetricTypes;
|
||||
}) {
|
||||
const { services } = useKibana<ApmPluginStartDeps>();
|
||||
const {
|
||||
lens: { EmbeddableComponent, navigateToPrefilledEditor, canUseEditor },
|
||||
} = services;
|
||||
|
||||
const lensAttributes = useMemo(
|
||||
() =>
|
||||
getLensAttributes({
|
||||
kuery,
|
||||
filters,
|
||||
metric,
|
||||
}),
|
||||
[kuery, filters, metric]
|
||||
);
|
||||
|
||||
const openInLens = useCallback(() => {
|
||||
if (lensAttributes) {
|
||||
navigateToPrefilledEditor(
|
||||
{
|
||||
id: `dataVisualizer-${metric}`,
|
||||
timeRange: {
|
||||
from: start,
|
||||
to: end,
|
||||
},
|
||||
attributes: lensAttributes,
|
||||
},
|
||||
{
|
||||
openInNewTab: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
}, [navigateToPrefilledEditor, lensAttributes, start, end, metric]);
|
||||
|
||||
const getOpenInLensAction = () => {
|
||||
return {
|
||||
id: 'openInLens',
|
||||
type: 'link',
|
||||
getDisplayName() {
|
||||
return i18n.translate('xpack.apm.serviceOverview.openInLens', {
|
||||
defaultMessage: 'Open in Lens',
|
||||
});
|
||||
},
|
||||
getIconType() {
|
||||
return 'visArea';
|
||||
},
|
||||
async isCompatible() {
|
||||
return true;
|
||||
},
|
||||
async execute() {
|
||||
openInLens();
|
||||
return;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiPanel hasBorder={true}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xs">
|
||||
<h2>{title}</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EmbeddableComponent
|
||||
viewMode={ViewMode.VIEW}
|
||||
id={`most-used-${metric.replaceAll('.', '-')}`}
|
||||
hidePanelTitles
|
||||
withDefaultActions
|
||||
style={{ height: 200 }}
|
||||
attributes={lensAttributes}
|
||||
timeRange={{
|
||||
from: start,
|
||||
to: end,
|
||||
}}
|
||||
{...(canUseEditor() && { extraActions: [getOpenInLensAction()] })}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiPanel>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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 { render } from '@testing-library/react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import React, { ReactNode } from 'react';
|
||||
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
|
||||
import { MockApmPluginContextWrapper } from '../../../../../context/apm_plugin/mock_apm_plugin_context';
|
||||
import { getLensAttributes } from './get_lens_attributes';
|
||||
import { MostUsedChart, MostUsedMetricTypes } from '.';
|
||||
import { HOST_OS_VERSION } from '../../../../../../common/elasticsearch_fieldnames';
|
||||
|
||||
const mockEmbeddableComponent = jest.fn();
|
||||
|
||||
function Wrapper({ children }: { children?: ReactNode }) {
|
||||
const KibanaReactContext = createKibanaReactContext({
|
||||
lens: {
|
||||
EmbeddableComponent: mockEmbeddableComponent.mockReturnValue(
|
||||
<div data-test-subj="lens-mock" />
|
||||
),
|
||||
canUseEditor: jest.fn(() => true),
|
||||
navigateToPrefilledEditor: jest.fn(),
|
||||
},
|
||||
} as Partial<CoreStart>);
|
||||
|
||||
return (
|
||||
<MemoryRouter>
|
||||
<KibanaReactContext.Provider>
|
||||
<MockApmPluginContextWrapper>{children}</MockApmPluginContextWrapper>
|
||||
</KibanaReactContext.Provider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
}
|
||||
|
||||
const renderOptions = { wrapper: Wrapper };
|
||||
|
||||
describe('Most used chart with Lens', () => {
|
||||
const props = {
|
||||
metric: HOST_OS_VERSION as MostUsedMetricTypes,
|
||||
filters: [
|
||||
{
|
||||
meta: {},
|
||||
query: {
|
||||
term: {
|
||||
'processor.event': 'transaction',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
meta: {},
|
||||
query: {
|
||||
term: {
|
||||
'service.name': 'opbeans-swift',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
meta: {},
|
||||
query: {
|
||||
term: {
|
||||
'transaction.type': 'request',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
test('gets lens attributes', () => {
|
||||
expect(getLensAttributes(props)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Renders most used chart with Lens', () => {
|
||||
const start = '2022-10-30T20%3A52%3A47.080Z';
|
||||
const end = '2022-10-31T20%3A52%3A47.080Z';
|
||||
|
||||
render(
|
||||
<MostUsedChart
|
||||
title="Most used os version"
|
||||
start={start}
|
||||
end={end}
|
||||
metric={HOST_OS_VERSION as MostUsedMetricTypes}
|
||||
filters={props.filters}
|
||||
/>,
|
||||
renderOptions
|
||||
);
|
||||
|
||||
expect(mockEmbeddableComponent).toHaveBeenCalledTimes(1);
|
||||
expect(mockEmbeddableComponent.mock.calls[0][0]).toEqual(
|
||||
expect.objectContaining({
|
||||
timeRange: {
|
||||
from: start,
|
||||
to: end,
|
||||
},
|
||||
attributes: getLensAttributes(props),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
|
@ -18,10 +18,16 @@ import { TransactionsTable } from '../../../shared/transactions_table';
|
|||
import { AggregatedTransactionsBadge } from '../../../shared/aggregated_transactions_badge';
|
||||
import { useApmParams } from '../../../../hooks/use_apm_params';
|
||||
import { useTimeRange } from '../../../../hooks/use_time_range';
|
||||
import { MostUsedChart } from './most_used_chart';
|
||||
import { LatencyMap } from './latency_map';
|
||||
import { MobileFilters } from './filters';
|
||||
import { useFiltersForMobileCharts } from './use_filters_for_mobile_charts';
|
||||
|
||||
import {
|
||||
DEVICE_MODEL_NAME,
|
||||
HOST_OS_VERSION,
|
||||
NETWORK_CONNECTION_TYPE,
|
||||
SERVICE_VERSION,
|
||||
} from '../../../../../common/elasticsearch_fieldnames';
|
||||
interface Props {
|
||||
latencyChartHeight: number;
|
||||
rowDirection: 'column' | 'row';
|
||||
|
@ -46,10 +52,10 @@ export function ServiceOverviewMobileCharts({
|
|||
kuery,
|
||||
rangeFrom,
|
||||
rangeTo,
|
||||
netConnectionType,
|
||||
device,
|
||||
osVersion,
|
||||
appVersion,
|
||||
netConnectionType,
|
||||
},
|
||||
} = useApmParams('/services/{serviceName}/overview');
|
||||
|
||||
|
@ -148,11 +154,82 @@ export function ServiceOverviewMobileCharts({
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem>
|
||||
<EuiPanel hasBorder={true}>
|
||||
<LatencyMap filters={filters} />
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup direction={rowDirection} gutterSize="s">
|
||||
{/* Device */}
|
||||
<EuiFlexItem>
|
||||
<MostUsedChart
|
||||
title={i18n.translate(
|
||||
'xpack.apm.serviceOverview.mostUsed.device',
|
||||
{
|
||||
defaultMessage: 'Most used device',
|
||||
}
|
||||
)}
|
||||
metric={DEVICE_MODEL_NAME}
|
||||
start={start}
|
||||
end={end}
|
||||
kuery={kuery}
|
||||
filters={filters}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
{/* NCT */}
|
||||
<EuiFlexItem>
|
||||
<MostUsedChart
|
||||
title={i18n.translate('xpack.apm.serviceOverview.mostUsed.nct', {
|
||||
defaultMessage: 'Most used NCT',
|
||||
})}
|
||||
metric={NETWORK_CONNECTION_TYPE}
|
||||
start={start}
|
||||
end={end}
|
||||
kuery={kuery}
|
||||
filters={filters}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup direction={rowDirection} gutterSize="s">
|
||||
{/* OS Version */}
|
||||
<EuiFlexItem>
|
||||
<MostUsedChart
|
||||
title={i18n.translate(
|
||||
'xpack.apm.serviceOverview.mostUsed.osVersion',
|
||||
{
|
||||
defaultMessage: 'Most used OS version',
|
||||
}
|
||||
)}
|
||||
metric={HOST_OS_VERSION}
|
||||
start={start}
|
||||
end={end}
|
||||
kuery={kuery}
|
||||
filters={filters}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
{/* App version */}
|
||||
<EuiFlexItem>
|
||||
<MostUsedChart
|
||||
title={i18n.translate(
|
||||
'xpack.apm.serviceOverview.mostUsed.appVersion',
|
||||
{
|
||||
defaultMessage: 'Most used app version',
|
||||
}
|
||||
)}
|
||||
metric={SERVICE_VERSION}
|
||||
start={start}
|
||||
end={end}
|
||||
kuery={kuery}
|
||||
filters={filters}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
TRANSACTION_TYPE,
|
||||
PROCESSOR_EVENT,
|
||||
HOST_OS_VERSION,
|
||||
DEVICE_MODEL_IDENTIFIER,
|
||||
DEVICE_MODEL_NAME,
|
||||
NETWORK_CONNECTION_TYPE,
|
||||
SERVICE_VERSION,
|
||||
} from '../../../../../common/elasticsearch_fieldnames';
|
||||
|
@ -52,7 +52,7 @@ export function useFiltersForMobileCharts() {
|
|||
...termQuery(SERVICE_NAME, serviceName),
|
||||
...termQuery(TRANSACTION_TYPE, transactionType),
|
||||
...termQuery(HOST_OS_VERSION, osVersion),
|
||||
...termQuery(DEVICE_MODEL_IDENTIFIER, device),
|
||||
...termQuery(DEVICE_MODEL_NAME, device),
|
||||
...termQuery(NETWORK_CONNECTION_TYPE, netConnectionType),
|
||||
...termQuery(SERVICE_VERSION, appVersion),
|
||||
...environmentQuery(environment),
|
||||
|
|
|
@ -21,6 +21,7 @@ import type {
|
|||
DataPublicPluginStart,
|
||||
DataPublicPluginSetup,
|
||||
} from '@kbn/data-plugin/public';
|
||||
import { LensPublicStart } from '@kbn/lens-plugin/public';
|
||||
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
|
||||
import type { EmbeddableStart } from '@kbn/embeddable-plugin/public';
|
||||
import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
|
||||
|
@ -97,6 +98,7 @@ export interface ApmPluginStartDeps {
|
|||
dataViews: DataViewsPublicPluginStart;
|
||||
unifiedSearch: UnifiedSearchPublicPluginStart;
|
||||
storage: IStorageWrapper;
|
||||
lens: LensPublicStart;
|
||||
}
|
||||
|
||||
const servicesTitle = i18n.translate('xpack.apm.navigation.servicesTitle', {
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
rangeQuery,
|
||||
} from '@kbn/observability-plugin/server';
|
||||
import {
|
||||
DEVICE_MODEL_IDENTIFIER,
|
||||
DEVICE_MODEL_NAME,
|
||||
HOST_OS_VERSION,
|
||||
NETWORK_CONNECTION_TYPE,
|
||||
SERVICE_NAME,
|
||||
|
@ -76,7 +76,7 @@ export async function getMobileFilters({
|
|||
aggs: {
|
||||
devices: {
|
||||
terms: {
|
||||
field: DEVICE_MODEL_IDENTIFIER,
|
||||
field: DEVICE_MODEL_NAME,
|
||||
size: 10,
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue