Skip to content

Commit cd1a10a

Browse files
committed
Merge branch 'master' into use-simple-line-curve
2 parents c828855 + 5511f0f commit cd1a10a

26 files changed

Lines changed: 8384 additions & 413 deletions

File tree

src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,13 @@ describe('IndexPatterns', () => {
113113
test('caches saved objects', async () => {
114114
await indexPatterns.getIds();
115115
await indexPatterns.getTitles();
116-
await indexPatterns.getFields(['id', 'title']);
117116
expect(savedObjectsClient.find).toHaveBeenCalledTimes(1);
118117
});
119118

120119
test('can refresh the saved objects caches', async () => {
121120
await indexPatterns.getIds();
122121
await indexPatterns.getTitles(true);
123-
await indexPatterns.getFields(['id', 'title'], true);
124-
expect(savedObjectsClient.find).toHaveBeenCalledTimes(3);
122+
expect(savedObjectsClient.find).toHaveBeenCalledTimes(2);
125123
});
126124

127125
test('deletes the index pattern', async () => {

src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ const indexPatternCache = createIndexPatternCache();
4141
const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3;
4242
const savedObjectType = 'index-pattern';
4343

44-
type IndexPatternCachedFieldType = 'id' | 'title';
45-
4644
export interface IndexPatternSavedObjectAttrs {
4745
title: string;
4846
}
@@ -116,22 +114,6 @@ export class IndexPatternsService {
116114
return this.savedObjectsCache.map((obj) => obj?.attributes?.title);
117115
};
118116

119-
getFields = async (fields: IndexPatternCachedFieldType[], refresh: boolean = false) => {
120-
if (!this.savedObjectsCache || refresh) {
121-
await this.refreshSavedObjectsCache();
122-
}
123-
if (!this.savedObjectsCache) {
124-
return [];
125-
}
126-
return this.savedObjectsCache.map((obj: Record<string, any>) => {
127-
const result: Partial<Record<IndexPatternCachedFieldType, string>> = {};
128-
fields.forEach(
129-
(f: IndexPatternCachedFieldType) => (result[f] = obj[f] || obj?.attributes?.[f])
130-
);
131-
return result;
132-
});
133-
};
134-
135117
getFieldsForTimePattern = (options: GetFieldsOptions = {}) => {
136118
return this.apiClient.getFieldsForTimePattern(options);
137119
};

src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.test.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ describe('Flyout', () => {
6464
done: jest.fn(),
6565
newIndexPatternUrl: '',
6666
indexPatterns: {
67-
getFields: jest.fn().mockImplementation(() => [{ id: '1' }, { id: '2' }]),
67+
getCache: jest.fn().mockImplementation(() => [
68+
{ id: '1', attributes: {} },
69+
{ id: '2', attributes: {} },
70+
]),
6871
} as any,
6972
overlays,
7073
http,

src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ export class Flyout extends Component<FlyoutProps, FlyoutState> {
132132
}
133133

134134
fetchIndexPatterns = async () => {
135-
const indexPatterns = await this.props.indexPatterns.getFields(['id', 'title']);
135+
const indexPatterns = (await this.props.indexPatterns.getCache())?.map((savedObject) => ({
136+
id: savedObject.id,
137+
title: savedObject.attributes.title,
138+
}));
136139
this.setState({ indexPatterns } as any);
137140
};
138141

x-pack/plugins/apm/public/components/app/RumDashboard/CoreVitals/index.tsx

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,22 @@
55
*/
66
import * as React from 'react';
77
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
8-
9-
import { useFetcher } from '../../../../hooks/useFetcher';
10-
import { useUrlParams } from '../../../../hooks/useUrlParams';
118
import { CLS_LABEL, FID_LABEL, LCP_LABEL } from './translations';
129
import { CoreVitalItem } from './CoreVitalItem';
10+
import { UXMetrics } from '../UXMetrics';
1311

1412
const CoreVitalsThresholds = {
1513
LCP: { good: '2.5s', bad: '4.0s' },
1614
FID: { good: '100ms', bad: '300ms' },
1715
CLS: { good: '0.1', bad: '0.25' },
1816
};
1917

20-
export function CoreVitals() {
21-
const { urlParams, uiFilters } = useUrlParams();
22-
23-
const { start, end } = urlParams;
24-
25-
const { data, status } = useFetcher(
26-
(callApmApi) => {
27-
const { serviceName } = uiFilters;
28-
if (start && end && serviceName) {
29-
return callApmApi({
30-
pathname: '/api/apm/rum-client/web-core-vitals',
31-
params: {
32-
query: { start, end, uiFilters: JSON.stringify(uiFilters) },
33-
},
34-
});
35-
}
36-
return Promise.resolve(null);
37-
},
38-
[start, end, uiFilters]
39-
);
18+
interface Props {
19+
data?: UXMetrics | null;
20+
loading: boolean;
21+
}
4022

23+
export function CoreVitals({ data, loading }: Props) {
4124
const { lcp, lcpRanks, fid, fidRanks, cls, clsRanks } = data || {};
4225

4326
return (
@@ -47,7 +30,7 @@ export function CoreVitals() {
4730
title={LCP_LABEL}
4831
value={lcp ? lcp + 's' : '0'}
4932
ranks={lcpRanks}
50-
loading={status !== 'success'}
33+
loading={loading}
5134
thresholds={CoreVitalsThresholds.LCP}
5235
/>
5336
</EuiFlexItem>
@@ -56,7 +39,7 @@ export function CoreVitals() {
5639
title={FID_LABEL}
5740
value={fid ? fid + 's' : '0'}
5841
ranks={fidRanks}
59-
loading={status !== 'success'}
42+
loading={loading}
6043
thresholds={CoreVitalsThresholds.FID}
6144
/>
6245
</EuiFlexItem>
@@ -65,7 +48,7 @@ export function CoreVitals() {
6548
title={CLS_LABEL}
6649
value={cls ?? '0'}
6750
ranks={clsRanks}
68-
loading={status !== 'success'}
51+
loading={loading}
6952
thresholds={CoreVitalsThresholds.CLS}
7053
/>
7154
</EuiFlexItem>

x-pack/plugins/apm/public/components/app/RumDashboard/CoreVitals/translations.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@ export const TBT_LABEL = i18n.translate('xpack.apm.rum.coreVitals.tbt', {
2626
defaultMessage: 'Total blocking time',
2727
});
2828

29+
export const NO_OF_LONG_TASK = i18n.translate(
30+
'xpack.apm.rum.uxMetrics.noOfLongTasks',
31+
{
32+
defaultMessage: 'No. of long tasks',
33+
}
34+
);
35+
36+
export const LONGEST_LONG_TASK = i18n.translate(
37+
'xpack.apm.rum.uxMetrics.longestLongTasks',
38+
{
39+
defaultMessage: 'Longest long task duration',
40+
}
41+
);
42+
43+
export const SUM_LONG_TASKS = i18n.translate(
44+
'xpack.apm.rum.uxMetrics.sumLongTasks',
45+
{
46+
defaultMessage: 'Total long tasks duration',
47+
}
48+
);
49+
2950
export const POOR_LABEL = i18n.translate('xpack.apm.rum.coreVitals.poor', {
3051
defaultMessage: 'a poor',
3152
});

x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { PageViewsTrend } from './PageViewsTrend';
1717
import { PageLoadDistribution } from './PageLoadDistribution';
1818
import { I18LABELS } from './translations';
1919
import { VisitorBreakdown } from './VisitorBreakdown';
20-
import { CoreVitals } from './CoreVitals';
20+
import { UXMetrics } from './UXMetrics';
2121
import { VisitorBreakdownMap } from './VisitorBreakdownMap';
2222

2323
export function RumDashboard() {
@@ -37,17 +37,7 @@ export function RumDashboard() {
3737
</EuiPanel>
3838
</EuiFlexItem>
3939
<EuiFlexItem>
40-
<EuiPanel>
41-
<EuiFlexGroup justifyContent="spaceBetween">
42-
<EuiFlexItem grow={1} data-cy={`client-metrics`}>
43-
<EuiTitle size="xs">
44-
<h3>{I18LABELS.coreWebVitals}</h3>
45-
</EuiTitle>
46-
<EuiSpacer size="s" />
47-
<CoreVitals />
48-
</EuiFlexItem>
49-
</EuiFlexGroup>
50-
</EuiPanel>
40+
<UXMetrics />
5141
</EuiFlexItem>
5242
<EuiFlexItem>
5343
<EuiFlexGroup gutterSize="s" wrap>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import React from 'react';
8+
import { EuiFlexItem, EuiStat, EuiFlexGroup } from '@elastic/eui';
9+
import { UXMetrics } from './index';
10+
import {
11+
FCP_LABEL,
12+
LONGEST_LONG_TASK,
13+
NO_OF_LONG_TASK,
14+
SUM_LONG_TASKS,
15+
TBT_LABEL,
16+
} from '../CoreVitals/translations';
17+
import { useUrlParams } from '../../../../hooks/useUrlParams';
18+
import { useFetcher } from '../../../../hooks/useFetcher';
19+
20+
export function formatToSec(
21+
value?: number | string,
22+
fromUnit = 'MicroSec'
23+
): string {
24+
const valueInMs = Number(value ?? 0) / (fromUnit === 'MicroSec' ? 1000 : 1);
25+
26+
if (valueInMs < 1000) {
27+
return valueInMs + ' ms';
28+
}
29+
return (valueInMs / 1000).toFixed(2) + ' s';
30+
}
31+
const STAT_STYLE = { width: '240px' };
32+
33+
interface Props {
34+
data?: UXMetrics | null;
35+
loading: boolean;
36+
}
37+
38+
export function KeyUXMetrics({ data, loading }: Props) {
39+
const { urlParams, uiFilters } = useUrlParams();
40+
41+
const { start, end, serviceName } = urlParams;
42+
43+
const { data: longTaskData, status } = useFetcher(
44+
(callApmApi) => {
45+
if (start && end && serviceName) {
46+
return callApmApi({
47+
pathname: '/api/apm/rum-client/long-task-metrics',
48+
params: {
49+
query: { start, end, uiFilters: JSON.stringify(uiFilters) },
50+
},
51+
});
52+
}
53+
return Promise.resolve(null);
54+
},
55+
[start, end, serviceName, uiFilters]
56+
);
57+
58+
// Note: FCP value is in ms unit
59+
return (
60+
<EuiFlexGroup responsive={false}>
61+
<EuiFlexItem grow={false} style={STAT_STYLE}>
62+
<EuiStat
63+
titleSize="s"
64+
title={formatToSec(data?.fcp, 'ms')}
65+
description={FCP_LABEL}
66+
isLoading={loading}
67+
/>
68+
</EuiFlexItem>
69+
<EuiFlexItem grow={false} style={STAT_STYLE}>
70+
<EuiStat
71+
titleSize="s"
72+
title={formatToSec(data?.tbt)}
73+
description={TBT_LABEL}
74+
isLoading={loading}
75+
/>
76+
</EuiFlexItem>
77+
<EuiFlexItem grow={false} style={STAT_STYLE}>
78+
<EuiStat
79+
titleSize="s"
80+
title={longTaskData?.noOfLongTasks ?? 0}
81+
description={NO_OF_LONG_TASK}
82+
isLoading={status !== 'success'}
83+
/>
84+
</EuiFlexItem>
85+
<EuiFlexItem grow={false} style={STAT_STYLE}>
86+
<EuiStat
87+
titleSize="s"
88+
title={formatToSec(longTaskData?.longestLongTask)}
89+
description={LONGEST_LONG_TASK}
90+
isLoading={status !== 'success'}
91+
/>
92+
</EuiFlexItem>
93+
<EuiFlexItem grow={false} style={STAT_STYLE}>
94+
<EuiStat
95+
titleSize="s"
96+
title={formatToSec(longTaskData?.sumOfLongTasks)}
97+
description={SUM_LONG_TASKS}
98+
isLoading={status !== 'success'}
99+
/>
100+
</EuiFlexItem>
101+
</EuiFlexGroup>
102+
);
103+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { formatToSec } from '../KeyUXMetrics';
8+
9+
describe('FormatToSec', () => {
10+
test('it returns the expected value', () => {
11+
expect(formatToSec(3413000)).toStrictEqual('3.41 s');
12+
expect(formatToSec(15548000)).toStrictEqual('15.55 s');
13+
expect(formatToSec(1147.5, 'ms')).toStrictEqual('1.15 s');
14+
expect(formatToSec(114, 'ms')).toStrictEqual('114 ms');
15+
expect(formatToSec(undefined, 'ms')).toStrictEqual('0 ms');
16+
expect(formatToSec(undefined)).toStrictEqual('0 ms');
17+
expect(formatToSec('1123232')).toStrictEqual('1.12 s');
18+
});
19+
});

0 commit comments

Comments
 (0)