Skip to content

Commit

Permalink
Fixes for service overview layout (#86205) (#86299)
Browse files Browse the repository at this point in the history
* Fixes for service overview layout

* Use 3/7 instead of 4/6 for `grow` between charts/tables
* Decrease chart height
* Use "s" gutterSize on tables
* Decrease table height
* Use `TruncateWithToolTip` on errors and transactions tables to remove tooltip inline-block style
* Use `responsive={false}` on dependency titles so icon/name pairs don't wrap
* Use `responsive={false}` on spark plots so plot/value pairs don't wrap
* Use `responsive={false}` on latency chart and table titles so controls and links don't wrap
* Make the fixed sizing overrides for the tables only be applied when we're using a wide, non-mobile (> 992) viewport
* Switch to "mobile" viewport (with one item per row) at 992 instead of 768

Since you cannot control the breakpoints at which EUI switches to "responsive" mode, we trigger these manually to change the number of columns. and whether or not the tables use a fixed height.

The overview now has three "modes":

* Two columns for chart/table rows
* Tables in non-responsive mode

* One column for charts/tables
* Tables in non-responsive mode

* One column for charts/tables
* Tables in non-responsive mode

Fixes #85781.

* remove unused imports

Co-authored-by: Nathan L Smith <[email protected]>
  • Loading branch information
ogupte and smith authored Dec 17, 2020
1 parent 42fcefa commit 59702c7
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 74 deletions.
38 changes: 28 additions & 10 deletions x-pack/plugins/apm/public/components/app/service_overview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ import { ServiceOverviewErrorsTable } from './service_overview_errors_table';
import { ServiceOverviewInstancesTable } from './service_overview_instances_table';
import { ServiceOverviewThroughputChart } from './service_overview_throughput_chart';
import { ServiceOverviewTransactionsTable } from './service_overview_transactions_table';
import { useShouldUseMobileLayout } from './use_should_use_mobile_layout';

/**
* The height a chart should be if it's next to a table with 5 rows and a title.
* Add the height of the pagination row.
*/
export const chartHeight = 322;
export const chartHeight = 288;

interface ServiceOverviewProps {
agentName?: string;
Expand All @@ -40,6 +41,11 @@ export function ServiceOverview({
useTrackPageview({ app: 'apm', path: 'service_overview' });
useTrackPageview({ app: 'apm', path: 'service_overview', delay: 15000 });

// The default EuiFlexGroup breaks at 768, but we want to break at 992, so we
// observe the window width and set the flex directions of rows accordingly
const shouldUseMobileLayout = useShouldUseMobileLayout();
const rowDirection = shouldUseMobileLayout ? 'column' : 'row';

const { transactionType } = useApmServiceContext();
const transactionTypeLabel = i18n.translate(
'xpack.apm.serviceOverview.searchBar.transactionTypeLabel',
Expand All @@ -58,11 +64,15 @@ export function ServiceOverview({
</EuiPanel>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup gutterSize="s">
<EuiFlexItem grow={4}>
<EuiFlexGroup
direction={rowDirection}
gutterSize="s"
responsive={false}
>
<EuiFlexItem grow={3}>
<ServiceOverviewThroughputChart height={chartHeight} />
</EuiFlexItem>
<EuiFlexItem grow={6}>
<EuiFlexItem grow={7}>
<EuiPanel>
<ServiceOverviewTransactionsTable
serviceName={serviceName}
Expand All @@ -72,28 +82,36 @@ export function ServiceOverview({
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup gutterSize="s">
<EuiFlexGroup
direction={rowDirection}
gutterSize="s"
responsive={false}
>
{!isRumAgentName(agentName) && (
<EuiFlexItem grow={4}>
<EuiFlexItem grow={3}>
<TransactionErrorRateChart
height={chartHeight}
showAnnotations={false}
/>
</EuiFlexItem>
)}
<EuiFlexItem grow={6}>
<EuiFlexItem grow={7}>
<EuiPanel>
<ServiceOverviewErrorsTable serviceName={serviceName} />
</EuiPanel>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup gutterSize="s">
<EuiFlexItem grow={4}>
<EuiFlexGroup
direction={rowDirection}
gutterSize="s"
responsive={false}
>
<EuiFlexItem grow={3}>
<TransactionBreakdownChart showAnnotations={false} />
</EuiFlexItem>
<EuiFlexItem grow={6}>
<EuiFlexItem grow={7}>
<EuiPanel>
<ServiceOverviewDependenciesTable
serviceName={serviceName}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
<TruncateWithTooltip
text={item.name}
content={
<EuiFlexGroup gutterSize="s">
<EuiFlexGroup gutterSize="s" responsive={false}>
<EuiFlexItem grow={false}>
{item.type === 'service' ? (
<AgentIcon agentName={item.agentName} />
Expand Down Expand Up @@ -190,9 +190,9 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
}));

return (
<EuiFlexGroup direction="column">
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<EuiFlexGroup>
<EuiFlexGroup responsive={false}>
<EuiFlexItem>
<EuiTitle size="xs">
<h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,25 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
EuiBasicTable,
EuiBasicTableColumn,
EuiFlexGroup,
EuiFlexItem,
EuiTitle,
EuiToolTip,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import styled from 'styled-components';
import { EuiBasicTable } from '@elastic/eui';
import { asInteger } from '../../../../../common/utils/formatters';
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 { callApmApi } from '../../../../services/rest/createCallApmApi';
import { px, truncate, unit } from '../../../../style/variables';
import { px, unit } from '../../../../style/variables';
import { SparkPlot } from '../../../shared/charts/spark_plot';
import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink';
import { ErrorOverviewLink } from '../../../shared/Links/apm/ErrorOverviewLink';
import { TableFetchWrapper } from '../../../shared/table_fetch_wrapper';
import { TimestampTooltip } from '../../../shared/TimestampTooltip';
import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip';
import { ServiceOverviewTableContainer } from '../service_overview_table_container';
import { TableLinkFlexItem } from '../table_link_flex_item';

Expand All @@ -50,18 +49,6 @@ const DEFAULT_SORT = {
field: 'occurrences' as const,
};

const ErrorDetailLinkWrapper = styled.div`
width: 100%;
.euiToolTipAnchor {
width: 100% !important;
}
`;

const StyledErrorDetailLink = styled(ErrorDetailLink)`
display: block;
${truncate('100%')}
`;

export function ServiceOverviewErrorsTable({ serviceName }: Props) {
const {
urlParams: { start, end },
Expand All @@ -87,16 +74,17 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) {
}),
render: (_, { name, group_id: errorGroupId }) => {
return (
<ErrorDetailLinkWrapper>
<EuiToolTip delay="long" content={name}>
<StyledErrorDetailLink
<TruncateWithTooltip
text={name}
content={
<ErrorDetailLink
serviceName={serviceName}
errorGroupId={errorGroupId}
>
{name}
</StyledErrorDetailLink>
</EuiToolTip>
</ErrorDetailLinkWrapper>
</ErrorDetailLink>
}
/>
);
},
},
Expand Down Expand Up @@ -202,9 +190,9 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) {
} = data;

return (
<EuiFlexGroup direction="column">
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<EuiFlexGroup>
<EuiFlexGroup responsive={false}>
<EuiFlexItem>
<EuiTitle size="xs">
<h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export function ServiceOverviewInstancesTable({ serviceName }: Props) {
status === FETCH_STATUS.LOADING || status === FETCH_STATUS.PENDING;

return (
<EuiFlexGroup direction="column">
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<EuiTitle size="xs">
<h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,33 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { ReactNode } from 'react';
import styled from 'styled-components';
import { useShouldUseMobileLayout } from './use_should_use_mobile_layout';

/**
* The height for a table on the overview page. Is the height of a 5-row basic
* table.
*/
const tableHeight = 298;
const tableHeight = 282;

/**
* A container for the table. Sets height and flex properties on the EUI Basic
* Table contained within and the first child div of that. This makes it so the
* pagination controls always stay fixed at the bottom in the same position.
*
* Only do this when we're at a non-mobile breakpoint.
*
* Hide the empty message when we don't yet have any items and are still loading.
*/
export const ServiceOverviewTableContainer = styled.div<{
const ServiceOverviewTableContainerDiv = styled.div<{
isEmptyAndLoading: boolean;
shouldUseMobileLayout: boolean;
}>`
${({ shouldUseMobileLayout }) =>
shouldUseMobileLayout
? ''
: `
height: ${tableHeight}px;
display: flex;
flex-direction: column;
Expand All @@ -34,10 +43,29 @@ export const ServiceOverviewTableContainer = styled.div<{
> :first-child {
flex-grow: 1;
}
}
`}
.euiTableRowCell {
visibility: ${({ isEmptyAndLoading }) =>
isEmptyAndLoading ? 'hidden' : 'visible'};
}
`;

export function ServiceOverviewTableContainer({
children,
isEmptyAndLoading,
}: {
children?: ReactNode;
isEmptyAndLoading: boolean;
}) {
const shouldUseMobileLayout = useShouldUseMobileLayout();

return (
<ServiceOverviewTableContainerDiv
isEmptyAndLoading={isEmptyAndLoading}
shouldUseMobileLayout={shouldUseMobileLayout}
>
{children}
</ServiceOverviewTableContainerDiv>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,37 @@
*/

import {
EuiBasicTable,
EuiBasicTableColumn,
EuiFlexGroup,
EuiFlexItem,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import styled from 'styled-components';
import { EuiToolTip } from '@elastic/eui';
import { ValuesType } from 'utility-types';
import { EuiBasicTable } from '@elastic/eui';
import { useLatencyAggregationType } from '../../../../hooks/use_latency_Aggregation_type';
import { LatencyAggregationType } from '../../../../../common/latency_aggregation_types';
import {
asDuration,
asPercent,
asTransactionRate,
} from '../../../../../common/utils/formatters';
import { px, truncate, unit } from '../../../../style/variables';
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 { useLatencyAggregationType } from '../../../../hooks/use_latency_Aggregation_type';
import {
APIReturnType,
callApmApi,
} from '../../../../services/rest/createCallApmApi';
import { px, unit } from '../../../../style/variables';
import { SparkPlot } from '../../../shared/charts/spark_plot';
import { ImpactBar } from '../../../shared/ImpactBar';
import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink';
import { TransactionOverviewLink } from '../../../shared/Links/apm/TransactionOverviewLink';
import { TableFetchWrapper } from '../../../shared/table_fetch_wrapper';
import { TableLinkFlexItem } from '../table_link_flex_item';
import { SparkPlot } from '../../../shared/charts/spark_plot';
import { ImpactBar } from '../../../shared/ImpactBar';
import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip';
import { ServiceOverviewTableContainer } from '../service_overview_table_container';
import { TableLinkFlexItem } from '../table_link_flex_item';

type ServiceTransactionGroupItem = ValuesType<
APIReturnType<'GET /api/apm/services/{serviceName}/transactions/groups/overview'>['transactionGroups']
Expand All @@ -55,18 +54,6 @@ const DEFAULT_SORT = {
field: 'impact' as const,
};

const TransactionGroupLinkWrapper = styled.div`
width: 100%;
.euiToolTipAnchor {
width: 100% !important;
}
`;

const StyledTransactionDetailLink = styled(TransactionDetailLink)`
display: block;
${truncate('100%')}
`;

function getLatencyAggregationTypeLabel(
latencyAggregationType?: LatencyAggregationType
) {
Expand Down Expand Up @@ -189,17 +176,18 @@ export function ServiceOverviewTransactionsTable({ serviceName }: Props) {
),
render: (_, { name, transactionType }) => {
return (
<TransactionGroupLinkWrapper>
<EuiToolTip delay="long" content={name}>
<StyledTransactionDetailLink
<TruncateWithTooltip
text={name}
content={
<TransactionDetailLink
serviceName={serviceName}
transactionName={name}
transactionType={transactionType}
>
{name}
</StyledTransactionDetailLink>
</EuiToolTip>
</TransactionGroupLinkWrapper>
</TransactionDetailLink>
}
/>
);
},
},
Expand Down Expand Up @@ -274,9 +262,9 @@ export function ServiceOverviewTransactionsTable({ serviceName }: Props) {
];

return (
<EuiFlexGroup direction="column">
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexGroup justifyContent="spaceBetween" responsive={false}>
<EuiFlexItem>
<EuiTitle size="xs">
<h2>
Expand Down
Loading

0 comments on commit 59702c7

Please sign in to comment.