[i18n] APM translations for Error Group (#28314)

* Translations for ErrorGroup

* Make occurrencesCount required

* Update message ids
This commit is contained in:
Maryia Lapata 2019-01-11 11:54:33 +03:00 committed by GitHub
parent 2937145f0f
commit 38163f2517
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 165 additions and 40 deletions

View file

@ -104,42 +104,61 @@ export function DetailView({ errorGroup, urlParams, location }: Props) {
}
const transactionLink = getTransactionLink(error, transaction);
const notAvailableLabel = i18n.translate(
'xpack.apm.errorGroupDetails.notAvailableLabel',
{
defaultMessage: 'N/A'
}
);
const stickyProperties = [
{
fieldName: '@timestamp',
label: 'Timestamp',
label: i18n.translate('xpack.apm.errorGroupDetails.timestampLabel', {
defaultMessage: 'Timestamp'
}),
val: error['@timestamp'],
width: '50%'
},
{
fieldName: REQUEST_URL_FULL,
label: 'URL',
val: get(error, REQUEST_URL_FULL, 'N/A'),
val: get(error, REQUEST_URL_FULL, notAvailableLabel),
truncated: true,
width: '50%'
},
{
fieldName: REQUEST_METHOD,
label: 'Request method',
val: get(error, REQUEST_METHOD, 'N/A'),
label: i18n.translate('xpack.apm.errorGroupDetails.requestMethodLabel', {
defaultMessage: 'Request method'
}),
val: get(error, REQUEST_METHOD, notAvailableLabel),
width: '25%'
},
{
fieldName: ERROR_EXC_HANDLED,
label: 'Handled',
val: String(get(error, ERROR_EXC_HANDLED, 'N/A')),
label: i18n.translate('xpack.apm.errorGroupDetails.handledLabel', {
defaultMessage: 'Handled'
}),
val: String(get(error, ERROR_EXC_HANDLED, notAvailableLabel)),
width: '25%'
},
{
fieldName: TRANSACTION_ID,
label: 'Transaction sample ID',
val: transactionLink || 'N/A',
label: i18n.translate(
'xpack.apm.errorGroupDetails.transactionSampleIdLabel',
{
defaultMessage: 'Transaction sample ID'
}
),
val: transactionLink || notAvailableLabel,
width: '25%'
},
{
fieldName: USER_ID,
label: 'User ID',
val: get(error, USER_ID, 'N/A'),
label: i18n.translate('xpack.apm.errorGroupDetails.userIdLabel', {
defaultMessage: 'User ID'
}),
val: get(error, USER_ID, notAvailableLabel),
width: '25%'
}
];
@ -151,11 +170,25 @@ export function DetailView({ errorGroup, urlParams, location }: Props) {
<Container>
<HeaderContainer>
<EuiTitle size="s">
<h3>Error occurrence</h3>
<h3>
{i18n.translate(
'xpack.apm.errorGroupDetails.errorOccurrenceTitle',
{
defaultMessage: 'Error occurrence'
}
)}
</h3>
</EuiTitle>
<DiscoverErrorButton error={error} kuery={urlParams.kuery}>
<EuiButtonEmpty iconType="discoverApp">
{`View ${occurrencesCount} occurrences in Discover`}
{i18n.translate(
'xpack.apm.errorGroupDetails.viewOccurrencesInDiscoverButtonLabel',
{
defaultMessage:
'View {occurrencesCount} occurrences in Discover',
values: { occurrencesCount }
}
)}
</EuiButtonEmpty>
</DiscoverErrorButton>
</HeaderContainer>

View file

@ -5,6 +5,7 @@
*/
import { EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import Histogram from '../../../shared/charts/Histogram';
import { EmptyMessage } from '../../../shared/EmptyMessage';
@ -23,7 +24,12 @@ export function getFormattedBuckets(buckets, bucketSize) {
});
}
function Distribution({ distribution, title = 'Occurrences' }) {
function Distribution({
distribution,
title = i18n.translate('xpack.apm.errorGroupDetails.occurrencesChartLabel', {
defaultMessage: 'Occurrences'
})
}) {
const buckets = getFormattedBuckets(
distribution.buckets,
distribution.bucketSize
@ -32,7 +38,13 @@ function Distribution({ distribution, title = 'Occurrences' }) {
const isEmpty = distribution.totalHits === 0;
if (isEmpty) {
return <EmptyMessage heading="No errors were found" />;
return (
<EmptyMessage
heading={i18n.translate('xpack.apm.errorGroupDetails.noErrorsLabel', {
defaultMessage: 'No errors were found'
})}
/>
);
}
return (
@ -45,8 +57,18 @@ function Distribution({ distribution, title = 'Occurrences' }) {
xType="time"
buckets={buckets}
bucketSize={distribution.bucketSize}
formatYShort={value => `${value} occ.`}
formatYLong={value => `${value} occurrences`}
formatYShort={value =>
i18n.translate('xpack.apm.errorGroupDetails.occurrencesShortLabel', {
defaultMessage: '{occCount} occ.',
values: { occCount: value }
})
}
formatYLong={value =>
i18n.translate('xpack.apm.errorGroupDetails.occurrencesLongLabel', {
defaultMessage: '{occCount} occurrences',
values: { occCount: value }
})
}
/>
</div>
);

View file

@ -5,6 +5,7 @@
*/
import { EuiBadge, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
import React, { Fragment } from 'react';
import styled from 'styled-components';
@ -57,9 +58,16 @@ const Culprit = styled.div`
font-family: ${fontFamilyCode};
`;
const notAvailableLabel = i18n.translate(
'xpack.apm.errorGroupDetails.notAvailableLabel',
{
defaultMessage: 'N/A'
}
);
function getShortGroupId(errorGroupId?: string) {
if (!errorGroupId) {
return 'N/A';
return notAvailableLabel;
}
return errorGroupId.slice(0, 5);
@ -87,9 +95,21 @@ export function ErrorGroupDetails({ urlParams, location }: Props) {
<div>
<EuiTitle>
<span>
Error group {getShortGroupId(urlParams.errorGroupId)}
{i18n.translate('xpack.apm.errorGroupDetails.errorGroupTitle', {
defaultMessage: 'Error group {errorGroupId}',
values: {
errorGroupId: getShortGroupId(urlParams.errorGroupId)
}
})}
{isUnhandled && (
<UnhandledBadge color="warning">Unhandled</UnhandledBadge>
<UnhandledBadge color="warning">
{i18n.translate(
'xpack.apm.errorGroupDetails.unhandledLabel',
{
defaultMessage: 'Unhandled'
}
)}
</UnhandledBadge>
)}
</span>
</EuiTitle>
@ -105,14 +125,35 @@ export function ErrorGroupDetails({ urlParams, location }: Props) {
<EuiText>
{logMessage && (
<Fragment>
<Label>Log message</Label>
<Label>
{i18n.translate(
'xpack.apm.errorGroupDetails.logMessageLabel',
{
defaultMessage: 'Log message'
}
)}
</Label>
<Message>{logMessage}</Message>
</Fragment>
)}
<Label>Exception message</Label>
<Message>{excMessage || 'N/A'}</Message>
<Label>Culprit</Label>
<Culprit>{culprit || 'N/A'}</Culprit>
<Label>
{i18n.translate(
'xpack.apm.errorGroupDetails.exceptionMessageLabel',
{
defaultMessage: 'Exception message'
}
)}
</Label>
<Message>{excMessage || notAvailableLabel}</Message>
<Label>
{i18n.translate(
'xpack.apm.errorGroupDetails.culpritLabel',
{
defaultMessage: 'Culprit'
}
)}
</Label>
<Culprit>{culprit || notAvailableLabel}</Culprit>
</EuiText>
</Titles>
)}

View file

@ -24,6 +24,7 @@ import {
fontSizes,
truncate
} from '../../../../style/variables';
import { i18n } from '@kbn/i18n';
function paginateItems({ items, pageIndex, pageSize }) {
return items.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize);
@ -47,6 +48,13 @@ const Culprit = styled.div`
font-family: ${fontFamilyCode};
`;
const notAvailableLabel = i18n.translate(
'xpack.apm.errorsTable.notAvailableLabel',
{
defaultMessage: 'N/A'
}
);
class List extends Component {
state = {
page: {
@ -82,33 +90,40 @@ class List extends Component {
const columns = [
{
name: 'Group ID',
name: i18n.translate('xpack.apm.errorsTable.groupIdColumnLabel', {
defaultMessage: 'Group ID'
}),
field: 'groupId',
sortable: false,
width: px(unit * 6),
render: groupId => {
return (
<GroupIdLink path={`/${serviceName}/errors/${groupId}`}>
{groupId.slice(0, 5) || 'N/A'}
{groupId.slice(0, 5) || notAvailableLabel}
</GroupIdLink>
);
}
},
{
name: 'Error message and culprit',
name: i18n.translate(
'xpack.apm.errorsTable.errorMessageAndCulpritColumnLabel',
{
defaultMessage: 'Error message and culprit'
}
),
field: 'message',
sortable: false,
width: '50%',
render: (message, item) => {
return (
<MessageAndCulpritCell>
<TooltipOverlay content={message || 'N/A'}>
<TooltipOverlay content={message || notAvailableLabel}>
<MessageLink path={`/${serviceName}/errors/${item.groupId}`}>
{message || 'N/A'}
{message || notAvailableLabel}
</MessageLink>
</TooltipOverlay>
<TooltipOverlay content={item.culprit || 'N/A'}>
<Culprit>{item.culprit || 'N/A'}</Culprit>
<TooltipOverlay content={item.culprit || notAvailableLabel}>
<Culprit>{item.culprit || notAvailableLabel}</Culprit>
</TooltipOverlay>
</MessageAndCulpritCell>
);
@ -121,28 +136,42 @@ class List extends Component {
align: 'right',
render: isUnhandled =>
isUnhandled === false && (
<EuiBadge color="warning">Unhandled</EuiBadge>
<EuiBadge color="warning">
{i18n.translate('xpack.apm.errorsTable.unhandledLabel', {
defaultMessage: 'Unhandled'
})}
</EuiBadge>
)
},
{
name: 'Occurrences',
name: i18n.translate('xpack.apm.errorsTable.occurrencesColumnLabel', {
defaultMessage: 'Occurrences'
}),
field: 'occurrenceCount',
sortable: true,
dataType: 'number',
render: value => (value ? numeral(value).format('0.[0]a') : 'N/A')
render: value =>
value ? numeral(value).format('0.[0]a') : notAvailableLabel
},
{
field: 'latestOccurrenceAt',
sortable: true,
name: 'Latest occurrence',
name: i18n.translate(
'xpack.apm.errorsTable.latestOccurrenceColumnLabel',
{
defaultMessage: 'Latest occurrence'
}
),
align: 'right',
render: value => (value ? moment(value).fromNow() : 'N/A')
render: value => (value ? moment(value).fromNow() : notAvailableLabel)
}
];
return (
<EuiBasicTable
noItemsMessage="No errors were found"
noItemsMessage={i18n.translate('xpack.apm.errorsTable.noErrorsLabel', {
defaultMessage: 'No errors were found'
})}
items={paginatedItems}
columns={columns}
pagination={{

View file

@ -14,7 +14,7 @@ import { IUrlParams } from '../urlParams';
import { createInitialDataSelector } from './helpers';
const ID = 'errorGroupDetails';
const INITIAL_DATA: ErrorGroupAPIResponse = {};
const INITIAL_DATA: ErrorGroupAPIResponse = { occurrencesCount: 0 };
const withInitialData = createInitialDataSelector(INITIAL_DATA);
export function getErrorGroupDetails(state: IReduxState) {

View file

@ -20,7 +20,7 @@ import { getTransaction } from '../transactions/get_transaction';
export interface ErrorGroupAPIResponse {
transaction?: Transaction;
error?: APMError;
occurrencesCount?: number;
occurrencesCount: number;
}
// TODO: rename from "getErrorGroup" to "getErrorGroupSample" (since a single error is returned, not an errorGroup)
@ -82,6 +82,6 @@ export async function getErrorGroup({
return {
transaction,
error,
occurrencesCount: oc(resp).hits.total()
occurrencesCount: resp.hits.total
};
}