Skip to content

Commit

Permalink
polish and improvements to correlations UI
Browse files Browse the repository at this point in the history
  • Loading branch information
ogupte committed Feb 5, 2021
1 parent d321f85 commit 9110ffa
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
*/

import React from 'react';
import { EuiIcon, EuiLink } from '@elastic/eui';
import {
EuiIcon,
EuiLink,
EuiBasicTable,
EuiBasicTableColumn,
EuiBadge,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useHistory } from 'react-router-dom';
import { EuiBasicTable } from '@elastic/eui';
import { EuiBasicTableColumn } from '@elastic/eui';
import { EuiCode } from '@elastic/eui';
import { asInteger, asPercent } from '../../../../common/utils/formatters';
import { APIReturnType } from '../../../services/rest/createCallApmApi';
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
Expand All @@ -30,13 +33,15 @@ interface Props<T> {
status: FETCH_STATUS;
cardinalityColumnName: string;
setSelectedSignificantTerm: (term: T | null) => void;
onFilter: () => void;
}

export function CorrelationsTable<T extends SignificantTerm>({
significantTerms,
status,
cardinalityColumnName,
setSelectedSignificantTerm,
onFilter,
}: Props<T>) {
const history = useHistory();
const columns: Array<EuiBasicTableColumn<T>> = [
Expand All @@ -48,7 +53,7 @@ export function CorrelationsTable<T extends SignificantTerm>({
{ defaultMessage: 'Score' }
),
render: (_: any, term: T) => {
return <EuiCode>{Math.round(term.score)}</EuiCode>;
return <EuiBadge>{Math.round(term.score)}</EuiBadge>;
},
},
{
Expand Down Expand Up @@ -96,6 +101,7 @@ export function CorrelationsTable<T extends SignificantTerm>({
)}"`,
},
});
onFilter();
},
},
{
Expand All @@ -117,6 +123,7 @@ export function CorrelationsTable<T extends SignificantTerm>({
)}"`,
},
});
onFilter();
},
},
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* 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 {
EuiFlexGroup,
EuiFlexItem,
EuiAccordion,
EuiComboBox,
EuiFormRow,
EuiLink,
EuiFieldNumber,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';

interface Props {
fieldNames: string[];
defaultFieldNames: string[];
setFieldNames: (fieldNames: string[]) => void;
setDurationPercentile?: (value: number) => void;
showThreshold?: boolean;
durationPercentile?: number;
}

export function CustomFields({
fieldNames,
setFieldNames,
defaultFieldNames,
setDurationPercentile = () => {},
showThreshold = false,
durationPercentile = 50,
}: Props) {
return (
<EuiAccordion
id="accordion"
buttonContent={i18n.translate(
'xpack.apm.correlations.customize.buttonLabel',
{ defaultMessage: 'Customize fields' }
)}
>
<EuiFlexGroup>
{showThreshold && (
<EuiFlexItem grow={1}>
<EuiFormRow
label={i18n.translate(
'xpack.apm.correlations.customize.thresholdLabel',
{ defaultMessage: 'Threshold' }
)}
helpText="Target percentile"
>
<EuiFieldNumber
value={durationPercentile.toString(10)}
onChange={(e) => {
const value = parseInt(e.currentTarget.value, 10);
if (isValidPercentile(value)) {
setDurationPercentile(value);
}
}}
prepend="%"
/>
</EuiFormRow>
</EuiFlexItem>
)}
<EuiFlexItem grow={4}>
<EuiFormRow
fullWidth={true}
label={i18n.translate(
'xpack.apm.correlations.customize.fieldLabel',
{
defaultMessage: 'Field',
}
)}
helpText={
<>
{i18n.translate(
'xpack.apm.correlations.customize.fieldHelpText',
{
defaultMessage: 'Fields to analyse for correlations.',
}
)}
&nbsp;
<EuiLink
type="reset"
onClick={() => {
setFieldNames(defaultFieldNames);
}}
>
{i18n.translate(
'xpack.apm.correlations.customize.fieldResetDefault',
{ defaultMessage: 'Reset to default' }
)}
</EuiLink>
</>
}
>
<EuiComboBox
fullWidth={true}
placeholder={i18n.translate(
'xpack.apm.correlations.customize.fieldPlaceholder',
{ defaultMessage: 'Select or create options' }
)}
selectedOptions={fieldNames.map((label) => ({ label }))}
onChange={(options) => {
const nextFieldNames = options.map((option) => option.label);
setFieldNames(nextFieldNames);
}}
onCreateOption={(term) => {
const nextFieldNames = [...fieldNames, term];
setFieldNames(nextFieldNames);
}}
/>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
</EuiAccordion>
);
}

function isValidPercentile(value: number) {
return !isNaN(value) && value >= 0 && value <= 100;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,7 @@ import {
} from '@elastic/charts';
import React, { useState } from 'react';
import { useParams } from 'react-router-dom';
import {
EuiTitle,
EuiFlexGroup,
EuiFlexItem,
EuiComboBox,
EuiAccordion,
} from '@elastic/eui';
import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
Expand All @@ -32,6 +26,8 @@ import { px } from '../../../style/variables';
import { CorrelationsTable } from './correlations_table';
import { ChartContainer } from '../../shared/charts/chart_container';
import { useTheme } from '../../../hooks/use_theme';
import { CustomFields } from './custom_fields';
import { useDefaultFieldNames } from './useDefaultFieldNames';

type CorrelationsApiResponse = NonNullable<
APIReturnType<'GET /api/apm/correlations/failed_transactions'>
Expand All @@ -41,26 +37,31 @@ type SignificantTerm = NonNullable<
CorrelationsApiResponse['significantTerms']
>[0];

const initialFieldNames = [
'transaction.name',
'user.username',
'user.id',
'host.ip',
'user_agent.name',
'kubernetes.pod.uuid',
'kubernetes.pod.name',
'url.domain',
'container.id',
'service.node.name',
].map((label) => ({ label }));
// const initialFieldNames = [
// 'transaction.name',
// 'user.username',
// 'user.id',
// 'host.ip',
// 'user_agent.name',
// 'kubernetes.pod.uuid',
// 'kubernetes.pod.name',
// 'url.domain',
// 'container.id',
// 'service.node.name',
// ].map((label) => ({ label }));

interface Props {
onClose: () => void;
}

export function ErrorCorrelations() {
export function ErrorCorrelations({ onClose }: Props) {
const [
selectedSignificantTerm,
setSelectedSignificantTerm,
] = useState<SignificantTerm | null>(null);

const [fieldNames, setFieldNames] = useState(initialFieldNames);
const defaultFieldNames = useDefaultFieldNames();
const [fieldNames, setFieldNames] = useState(defaultFieldNames);
const { serviceName } = useParams<{ serviceName?: string }>();
const { urlParams, uiFilters } = useUrlParams();
const { transactionName, transactionType, start, end } = urlParams;
Expand All @@ -78,7 +79,7 @@ export function ErrorCorrelations() {
start,
end,
uiFilters: JSON.stringify(uiFilters),
fieldNames: fieldNames.map((field) => field.label).join(','),
fieldNames: fieldNames.join(','),
},
},
});
Expand All @@ -99,7 +100,17 @@ export function ErrorCorrelations() {
<>
<EuiFlexGroup direction="column">
<EuiFlexItem>
<EuiTitle size="s">
<EuiText size="s">
<p>
Orbiting this at a distance of roughly ninety-two million miles is
an utterly insignificant little blue green planet whose ape-
descended life forms are so amazingly primitive that they still
think digital watches are a pretty neat idea.
</p>
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<EuiTitle size="xxs">
<h4>
{i18n.translate('xpack.apm.correlations.error.chart.title', {
defaultMessage: 'Error rate over time',
Expand All @@ -123,29 +134,15 @@ export function ErrorCorrelations() {
significantTerms={data?.significantTerms}
status={status}
setSelectedSignificantTerm={setSelectedSignificantTerm}
onFilter={onClose}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiAccordion
id="accordion"
buttonContent={i18n.translate(
'xpack.apm.correlations.customize.buttonLabel',
{ defaultMessage: 'Customize fields' }
)}
>
<EuiComboBox
fullWidth={true}
placeholder={i18n.translate(
'xpack.apm.correlations.customize.fieldPlaceholder',
{ defaultMessage: 'Select or create options' }
)}
selectedOptions={fieldNames}
onChange={setFieldNames}
onCreateOption={(term) =>
setFieldNames((names) => [...names, { label: term }])
}
/>
</EuiAccordion>
<CustomFields
defaultFieldNames={defaultFieldNames}
fieldNames={fieldNames}
setFieldNames={setFieldNames}
/>
</EuiFlexItem>
</EuiFlexGroup>
</>
Expand Down
21 changes: 11 additions & 10 deletions x-pack/plugins/apm/public/components/app/Correlations/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { enableCorrelations } from '../../../../common/ui_settings_keys';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { LatencyCorrelations } from './latency_correlations';
import { ErrorCorrelations } from './error_correlations';
import { ThroughputCorrelations } from './throughput_correlations';
// import { ThroughputCorrelations } from './throughput_correlations';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
import { createHref } from '../../shared/Links/url_helpers';
import { useLicenseContext } from '../../../context/license/use_license_context';
Expand All @@ -40,21 +40,22 @@ const latencyTab = {
}),
component: LatencyCorrelations,
};
const throughputTab = {
key: 'throughput',
label: i18n.translate('xpack.apm.correlations.tabs.throughputLabel', {
defaultMessage: 'Throughput',
}),
component: ThroughputCorrelations,
};
// const throughputTab = {
// key: 'throughput',
// label: i18n.translate('xpack.apm.correlations.tabs.throughputLabel', {
// defaultMessage: 'Throughput',
// }),
// component: ThroughputCorrelations,
// };
const errorRateTab = {
key: 'errorRate',
label: i18n.translate('xpack.apm.correlations.tabs.errorRateLabel', {
defaultMessage: 'Error rate',
}),
component: ErrorCorrelations,
};
const tabs = [latencyTab, throughputTab, errorRateTab];
// const tabs = [latencyTab, throughputTab, errorRateTab];
const tabs = [latencyTab, errorRateTab];

export function Correlations() {
const { uiSettings } = useApmPluginContext().core;
Expand Down Expand Up @@ -165,7 +166,7 @@ export function Correlations() {
))}
</EuiTabs>
<EuiSpacer />
<TabContent />
<TabContent onClose={() => setIsFlyoutVisible(false)} />
</EuiFlyoutBody>
</EuiFlyout>
</EuiPortal>
Expand Down
Loading

0 comments on commit 9110ffa

Please sign in to comment.