Skip to content

Commit 8da773c

Browse files
committed
Overview heights and loading states (#83360)
* Overview heights and loading states * Set the chart height to fill the whole container * Remove the initial loading spinner for the tables and always show the progress bar * Make the last seen column on the errors table a bit wider so it doesn't wrap * Make a `ServiceOverviewTable` component that pins the pagination to the bottom of the panel * Show the loading spinner on charts when doing updates
1 parent 7860685 commit 8da773c

6 files changed

Lines changed: 103 additions & 50 deletions

File tree

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

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
} from '@elastic/eui';
1414
import { i18n } from '@kbn/i18n';
1515
import React from 'react';
16-
import styled from 'styled-components';
1716
import { useTrackPageview } from '../../../../../observability/public';
1817
import { isRumAgentName } from '../../../../common/agent_name';
1918
import { ChartsSyncContextProvider } from '../../../context/charts_sync_context';
@@ -24,16 +23,11 @@ import { SearchBar } from '../../shared/search_bar';
2423
import { ServiceOverviewErrorsTable } from './service_overview_errors_table';
2524
import { TableLinkFlexItem } from './table_link_flex_item';
2625

27-
const rowHeight = 310;
28-
const latencyChartRowHeight = 230;
29-
30-
const Row = styled(EuiFlexItem)`
31-
height: ${rowHeight}px;
32-
`;
33-
34-
const LatencyChartRow = styled(EuiFlexItem)`
35-
height: ${latencyChartRowHeight}px;
36-
`;
26+
/**
27+
* The height a chart should be if it's next to a table with 5 rows and a title.
28+
* Add the height of the pagination row.
29+
*/
30+
export const chartHeight = 322;
3731

3832
interface ServiceOverviewProps {
3933
agentName?: string;
@@ -52,7 +46,7 @@ export function ServiceOverview({
5246
<SearchBar />
5347
<EuiPage>
5448
<EuiFlexGroup direction="column" gutterSize="s">
55-
<LatencyChartRow>
49+
<EuiFlexItem>
5650
<EuiPanel>
5751
<EuiTitle size="xs">
5852
<h2>
@@ -65,8 +59,8 @@ export function ServiceOverview({
6559
</h2>
6660
</EuiTitle>
6761
</EuiPanel>
68-
</LatencyChartRow>
69-
<Row>
62+
</EuiFlexItem>
63+
<EuiFlexItem>
7064
<EuiFlexGroup gutterSize="s">
7165
<EuiFlexItem grow={4}>
7266
<EuiPanel>
@@ -111,12 +105,15 @@ export function ServiceOverview({
111105
</EuiPanel>
112106
</EuiFlexItem>
113107
</EuiFlexGroup>
114-
</Row>
115-
<Row>
108+
</EuiFlexItem>
109+
<EuiFlexItem>
116110
<EuiFlexGroup gutterSize="s">
117111
{!isRumAgentName(agentName) && (
118112
<EuiFlexItem grow={4}>
119-
<TransactionErrorRateChart showAnnotations={false} />
113+
<TransactionErrorRateChart
114+
height={chartHeight}
115+
showAnnotations={false}
116+
/>
120117
</EuiFlexItem>
121118
)}
122119
<EuiFlexItem grow={6}>
@@ -125,8 +122,8 @@ export function ServiceOverview({
125122
</EuiPanel>
126123
</EuiFlexItem>
127124
</EuiFlexGroup>
128-
</Row>
129-
<Row>
125+
</EuiFlexItem>
126+
<EuiFlexItem>
130127
<EuiFlexGroup gutterSize="s">
131128
<EuiFlexItem grow={4}>
132129
<EuiPanel>
@@ -175,8 +172,8 @@ export function ServiceOverview({
175172
</EuiPanel>
176173
</EuiFlexItem>
177174
</EuiFlexGroup>
178-
</Row>
179-
<Row>
175+
</EuiFlexItem>
176+
<EuiFlexItem>
180177
<EuiFlexGroup gutterSize="s">
181178
<EuiFlexItem grow={4}>
182179
<EuiPanel>
@@ -207,7 +204,7 @@ export function ServiceOverview({
207204
</EuiPanel>
208205
</EuiFlexItem>
209206
</EuiFlexGroup>
210-
</Row>
207+
</EuiFlexItem>
211208
</EuiFlexGroup>
212209
</EuiPage>
213210
</ChartsSyncContextProvider>

x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/fetch_wrapper.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,20 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import React from 'react';
7+
import React, { ReactNode } from 'react';
88
import { FETCH_STATUS } from '../../../../hooks/useFetcher';
99
import { ErrorStatePrompt } from '../../../shared/ErrorStatePrompt';
10-
import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt';
1110

1211
export function FetchWrapper({
13-
hasData,
1412
status,
1513
children,
1614
}: {
17-
hasData: boolean;
1815
status: FETCH_STATUS;
19-
children: React.ReactNode;
16+
children: ReactNode;
2017
}) {
2118
if (status === FETCH_STATUS.FAILURE) {
2219
return <ErrorStatePrompt />;
2320
}
2421

25-
if (!hasData && status !== FETCH_STATUS.SUCCESS) {
26-
return <LoadingStatePrompt />;
27-
}
28-
2922
return <>{children}</>;
3023
}

x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,27 @@
33
* or more contributor license agreements. Licensed under the Elastic License;
44
* you may not use this file except in compliance with the Elastic License.
55
*/
6-
import React, { useState } from 'react';
7-
import { EuiTitle } from '@elastic/eui';
8-
import { EuiFlexItem } from '@elastic/eui';
9-
import { EuiFlexGroup } from '@elastic/eui';
6+
import {
7+
EuiBasicTableColumn,
8+
EuiFlexGroup,
9+
EuiFlexItem,
10+
EuiTitle,
11+
EuiToolTip,
12+
} from '@elastic/eui';
1013
import { i18n } from '@kbn/i18n';
11-
import { EuiBasicTable } from '@elastic/eui';
12-
import { EuiBasicTableColumn } from '@elastic/eui';
14+
import React, { useState } from 'react';
1315
import styled from 'styled-components';
14-
import { EuiToolTip } from '@elastic/eui';
1516
import { asInteger } from '../../../../../common/utils/formatters';
1617
import { FETCH_STATUS, useFetcher } from '../../../../hooks/useFetcher';
1718
import { useUrlParams } from '../../../../hooks/useUrlParams';
18-
import { ErrorOverviewLink } from '../../../shared/Links/apm/ErrorOverviewLink';
19-
import { TableLinkFlexItem } from '../table_link_flex_item';
20-
import { SparkPlotWithValueLabel } from '../../../shared/charts/spark_plot/spark_plot_with_value_label';
2119
import { callApmApi } from '../../../../services/rest/createCallApmApi';
22-
import { TimestampTooltip } from '../../../shared/TimestampTooltip';
23-
import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink';
2420
import { px, truncate, unit } from '../../../../style/variables';
21+
import { SparkPlotWithValueLabel } from '../../../shared/charts/spark_plot/spark_plot_with_value_label';
22+
import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink';
23+
import { ErrorOverviewLink } from '../../../shared/Links/apm/ErrorOverviewLink';
24+
import { TimestampTooltip } from '../../../shared/TimestampTooltip';
25+
import { ServiceOverviewTable } from '../service_overview_table';
26+
import { TableLinkFlexItem } from '../table_link_flex_item';
2527
import { FetchWrapper } from './fetch_wrapper';
2628

2729
interface Props {
@@ -108,7 +110,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) {
108110
render: (_, { last_seen: lastSeen }) => {
109111
return <TimestampTooltip time={lastSeen} timeUnit="minutes" />;
110112
},
111-
width: px(unit * 8),
113+
width: px(unit * 9),
112114
},
113115
{
114116
field: 'occurrences',
@@ -223,8 +225,8 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) {
223225
</EuiFlexGroup>
224226
</EuiFlexItem>
225227
<EuiFlexItem>
226-
<FetchWrapper hasData={!!items.length} status={status}>
227-
<EuiBasicTable
228+
<FetchWrapper status={status}>
229+
<ServiceOverviewTable
228230
columns={columns}
229231
items={items}
230232
pagination={{
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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 { EuiBasicTable, EuiBasicTableProps } from '@elastic/eui';
8+
import React from 'react';
9+
import styled from 'styled-components';
10+
11+
/**
12+
* The height for a table on the overview page. Is the height of a 5-row basic
13+
* table.
14+
*/
15+
const tableHeight = 298;
16+
17+
/**
18+
* A container for the table. Sets height and flex properties on the EUI Basic
19+
* Table contained within and the first child div of that. This makes it so the
20+
* pagination controls always stay fixed at the bottom in the same position.
21+
*
22+
* Hide the empty message when we don't yet have any items and are still loading.
23+
*/
24+
const ServiceOverviewTableContainer = styled.div<{
25+
isEmptyAndLoading: boolean;
26+
}>`
27+
height: ${tableHeight}px;
28+
display: flex;
29+
flex-direction: column;
30+
31+
.euiBasicTable {
32+
display: flex;
33+
flex-direction: column;
34+
flex-grow: 1;
35+
36+
> :first-child {
37+
flex-grow: 1;
38+
}
39+
}
40+
41+
.euiTableRowCell {
42+
visibility: ${({ isEmptyAndLoading }) =>
43+
isEmptyAndLoading ? 'hidden' : 'visible'};
44+
}
45+
`;
46+
47+
export function ServiceOverviewTable<T>(props: EuiBasicTableProps<T>) {
48+
const { items, loading } = props;
49+
const isEmptyAndLoading = !!(items.length === 0 && loading);
50+
51+
return (
52+
<ServiceOverviewTableContainer isEmptyAndLoading={isEmptyAndLoading}>
53+
<EuiBasicTable {...props} />
54+
</ServiceOverviewTableContainer>
55+
);
56+
}

x-pack/plugins/apm/public/components/shared/charts/line_chart/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { onBrushEnd } from '../helper/helper';
3131
interface Props {
3232
id: string;
3333
fetchStatus: FETCH_STATUS;
34+
height?: number;
3435
onToggleLegend?: LegendItemListener;
3536
timeseries: TimeSeries[];
3637
/**
@@ -44,10 +45,9 @@ interface Props {
4445
showAnnotations?: boolean;
4546
}
4647

47-
const XY_HEIGHT = unit * 16;
48-
4948
export function LineChart({
5049
id,
50+
height = unit * 16,
5151
fetchStatus,
5252
onToggleLegend,
5353
timeseries,
@@ -88,7 +88,7 @@ export function LineChart({
8888
);
8989

9090
return (
91-
<ChartContainer status={fetchStatus} hasData={!isEmpty} height={XY_HEIGHT}>
91+
<ChartContainer hasData={!isEmpty} height={height} status={fetchStatus}>
9292
<Chart ref={chartRef} id={id}>
9393
<Settings
9494
onBrushEnd={({ x }) => onBrushEnd({ x, history })}

x-pack/plugins/apm/public/components/shared/charts/transaction_error_rate_chart/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,14 @@ function yTickFormat(y?: number | null) {
2727
}
2828

2929
interface Props {
30+
height?: number;
3031
showAnnotations?: boolean;
3132
}
3233

33-
export function TransactionErrorRateChart({ showAnnotations = true }: Props) {
34+
export function TransactionErrorRateChart({
35+
height,
36+
showAnnotations = true,
37+
}: Props) {
3438
const theme = useTheme();
3539
const { serviceName } = useParams<{ serviceName?: string }>();
3640
const { urlParams, uiFilters } = useUrlParams();
@@ -71,6 +75,7 @@ export function TransactionErrorRateChart({ showAnnotations = true }: Props) {
7175
</EuiTitle>
7276
<LineChart
7377
id="errorRate"
78+
height={height}
7479
showAnnotations={showAnnotations}
7580
fetchStatus={status}
7681
timeseries={[

0 commit comments

Comments
 (0)