[i18n] APM translations (Part 1) (#27384)

* Translation for APM utils, intex.js and register_feature.js

* Fix a typo
This commit is contained in:
Maryia Lapata 2018-12-18 18:30:26 +03:00 committed by GitHub
parent d19cafb397
commit d555241ca7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 97 additions and 47 deletions

View file

@ -16,6 +16,7 @@
"timelion": "src/legacy/core_plugins/timelion", "timelion": "src/legacy/core_plugins/timelion",
"tagCloud": "src/legacy/core_plugins/tagcloud", "tagCloud": "src/legacy/core_plugins/tagcloud",
"tsvb": "src/legacy/core_plugins/metrics", "tsvb": "src/legacy/core_plugins/metrics",
"xpack.apm": "x-pack/plugins/apm",
"xpack.beatsManagement": "x-pack/plugins/beats_management", "xpack.beatsManagement": "x-pack/plugins/beats_management",
"xpack.graph": "x-pack/plugins/graph", "xpack.graph": "x-pack/plugins/graph",
"xpack.grokDebugger": "x-pack/plugins/grokdebugger", "xpack.grokDebugger": "x-pack/plugins/grokdebugger",

View file

@ -13,6 +13,7 @@ import { initStatusApi } from './server/routes/status_check';
import { initTracesApi } from './server/routes/traces'; import { initTracesApi } from './server/routes/traces';
import mappings from './mappings'; import mappings from './mappings';
import { makeApmUsageCollector } from './server/lib/apm_telemetry'; import { makeApmUsageCollector } from './server/lib/apm_telemetry';
import { i18n } from '@kbn/i18n';
export function apm(kibana) { export function apm(kibana) {
return new kibana.Plugin({ return new kibana.Plugin({
@ -24,7 +25,9 @@ export function apm(kibana) {
uiExports: { uiExports: {
app: { app: {
title: 'APM', title: 'APM',
description: 'APM for the Elastic Stack', description: i18n.translate('xpack.apm.apmForESDescription', {
defaultMessage: 'APM for the Elastic Stack'
}),
main: 'plugins/apm/index', main: 'plugins/apm/index',
icon: 'plugins/apm/icon.svg', icon: 'plugins/apm/icon.svg',
euiIconType: 'apmApp', euiIconType: 'apmApp',

View file

@ -11,13 +11,15 @@ import {
} from 'ui/registry/feature_catalogue'; } from 'ui/registry/feature_catalogue';
if (chrome.getInjected('apmUiEnabled')) { if (chrome.getInjected('apmUiEnabled')) {
FeatureCatalogueRegistryProvider.register(() => { FeatureCatalogueRegistryProvider.register(i18n => {
return { return {
id: 'apm', id: 'apm',
title: 'APM', title: 'APM',
description: description: i18n('xpack.apm.apmDescription', {
'Automatically collect in-depth performance metrics and ' + defaultMessage:
'errors from inside your applications.', 'Automatically collect in-depth performance metrics and ' +
'errors from inside your applications.'
}),
icon: 'apmApp', icon: 'apmApp',
path: '/app/apm', path: '/app/apm',
showOnHomePage: true, showOnHomePage: true,

View file

@ -5,10 +5,18 @@
*/ */
import numeral from '@elastic/numeral'; import numeral from '@elastic/numeral';
import { i18n } from '@kbn/i18n';
import { memoize } from 'lodash'; import { memoize } from 'lodash';
const SECONDS_CUT_OFF = 10 * 1000000; // 10 seconds (in microseconds) const SECONDS_CUT_OFF = 10 * 1000000; // 10 seconds (in microseconds)
const MILLISECONDS_CUT_OFF = 10 * 1000; // 10 milliseconds (in microseconds) const MILLISECONDS_CUT_OFF = 10 * 1000; // 10 milliseconds (in microseconds)
const SPACE = ' ';
const notAvailableLabel: string = i18n.translate(
'xpack.apm.formatters.notAvailableLabel',
{
defaultMessage: 'N/A'
}
);
/* /*
* value: time in microseconds * value: time in microseconds
@ -23,45 +31,57 @@ interface FormatterOptions {
export function asSeconds( export function asSeconds(
value: FormatterValue, value: FormatterValue,
{ withUnit = true, defaultValue = 'N/A' }: FormatterOptions = {} { withUnit = true, defaultValue = notAvailableLabel }: FormatterOptions = {}
) { ) {
if (value == null) { if (value == null) {
return defaultValue; return defaultValue;
} }
const secondsLabel =
SPACE +
i18n.translate('xpack.apm.formatters.secondsTimeUnitLabel', {
defaultMessage: 's'
});
const formatted = asDecimal(value / 1000000); const formatted = asDecimal(value / 1000000);
return `${formatted}${withUnit ? ' s' : ''}`; return `${formatted}${withUnit ? secondsLabel : ''}`;
} }
export function asMillis( export function asMillis(
value: FormatterValue, value: FormatterValue,
{ withUnit = true, defaultValue = 'N/A' }: FormatterOptions = {} { withUnit = true, defaultValue = notAvailableLabel }: FormatterOptions = {}
) { ) {
if (value == null) { if (value == null) {
return defaultValue; return defaultValue;
} }
const millisLabel =
SPACE +
i18n.translate('xpack.apm.formatters.millisTimeUnitLabel', {
defaultMessage: 'ms'
});
const formatted = asInteger(value / 1000); const formatted = asInteger(value / 1000);
return `${formatted}${withUnit ? ' ms' : ''}`; return `${formatted}${withUnit ? millisLabel : ''}`;
} }
export function asMicros( export function asMicros(
value: FormatterValue, value: FormatterValue,
{ withUnit = true, defaultValue = 'N/A' }: FormatterOptions = {} { withUnit = true, defaultValue = notAvailableLabel }: FormatterOptions = {}
) { ) {
if (value == null) { if (value == null) {
return defaultValue; return defaultValue;
} }
const microsLabel =
SPACE +
i18n.translate('xpack.apm.formatters.microsTimeUnitLabel', {
defaultMessage: 'μs'
});
const formatted = asInteger(value); const formatted = asInteger(value);
return `${formatted}${withUnit ? ' μs' : ''}`; return `${formatted}${withUnit ? microsLabel : ''}`;
} }
type TimeFormatter = ( type TimeFormatter = (
max: number max: number
) => ( ) => (value: FormatterValue, options: FormatterOptions) => string;
value: FormatterValue,
{ withUnit, defaultValue }: FormatterOptions
) => string;
export const getTimeFormatter: TimeFormatter = memoize((max: number) => { export const getTimeFormatter: TimeFormatter = memoize((max: number) => {
const unit = timeUnit(max); const unit = timeUnit(max);
@ -87,7 +107,7 @@ export function timeUnit(max: number) {
export function asTime( export function asTime(
value: FormatterValue, value: FormatterValue,
{ withUnit = true, defaultValue = 'N/A' }: FormatterOptions = {} { withUnit = true, defaultValue = notAvailableLabel }: FormatterOptions = {}
) { ) {
if (value == null) { if (value == null) {
return defaultValue; return defaultValue;
@ -105,7 +125,13 @@ export function asInteger(value: number) {
} }
export function tpmUnit(type: string) { export function tpmUnit(type: string) {
return type === 'request' ? 'rpm' : 'tpm'; return type === 'request'
? i18n.translate('xpack.apm.formatters.requestsPerMinLabel', {
defaultMessage: 'rpm'
})
: i18n.translate('xpack.apm.formatters.transactionsPerMinLabel', {
defaultMessage: 'tpm'
});
} }
export function asPercent( export function asPercent(

View file

@ -37,38 +37,48 @@ export function initTimepicker(history, dispatch) {
uiModules uiModules
.get('app/apm', []) .get('app/apm', [])
.controller('TimePickerController', ($scope, globalState, $rootScope) => { .controller(
// Add APM feedback menu 'TimePickerController',
// TODO: move this somewhere else ($scope, globalState, $rootScope, i18n) => {
$scope.topNavMenu = []; // Add APM feedback menu
$scope.topNavMenu.push({ // TODO: move this somewhere else
key: 'APM feedback', $scope.topNavMenu = [];
description: 'APM feedback', $scope.topNavMenu.push({
tooltip: 'Provide feedback on APM', key: 'APM feedback',
template: require('../../templates/feedback_menu.html') label: i18n('xpack.apm.topNav.apmFeedbackLabel', {
}); defaultMessage: 'APM feedback'
}),
description: i18n('xpack.apm.topNav.apmFeedbackDescription', {
defaultMessage: 'APM feedback'
}),
tooltip: i18n('xpack.apm.topNav.apmFeedbackTooltip', {
defaultMessage: 'Provide feedback on APM'
}),
template: require('../../templates/feedback_menu.html')
});
history.listen(() => { history.listen(() => {
updateRefreshRate(dispatch);
globalState.fetch(); // ensure global state is updated when url changes
});
// ensure that redux is notified after timefilter has updated
$scope.$listen(timefilter, 'timeUpdate', () =>
dispatch(updateTimePickerAction())
);
// ensure that timepicker updates when global state changes
registerTimefilterWithGlobalState(globalState, $rootScope);
timefilter.enableTimeRangeSelector();
timefilter.enableAutoRefreshSelector();
dispatch(updateTimePickerAction());
updateRefreshRate(dispatch); updateRefreshRate(dispatch);
globalState.fetch(); // ensure global state is updated when url changes
});
// ensure that redux is notified after timefilter has updated Promise.all([waitForAngularReady]).then(resolve);
$scope.$listen(timefilter, 'timeUpdate', () => }
dispatch(updateTimePickerAction()) );
);
// ensure that timepicker updates when global state changes
registerTimefilterWithGlobalState(globalState, $rootScope);
timefilter.enableTimeRangeSelector();
timefilter.enableAutoRefreshSelector();
dispatch(updateTimePickerAction());
updateRefreshRate(dispatch);
Promise.all([waitForAngularReady]).then(resolve);
});
}); });
} }

View file

@ -5,6 +5,7 @@
*/ */
import { EuiLink, EuiLinkAnchorProps } from '@elastic/eui'; import { EuiLink, EuiLinkAnchorProps } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import createHistory from 'history/createHashHistory'; import createHistory from 'history/createHashHistory';
import { get, isPlainObject, mapValues } from 'lodash'; import { get, isPlainObject, mapValues } from 'lodash';
import qs from 'querystring'; import qs from 'querystring';
@ -26,6 +27,13 @@ const DEFAULT_KIBANA_TIME_RANGE = {
} }
}; };
const viewJobLabel: string = i18n.translate(
'xpack.apm.viewMLJob.viewJobLabel',
{
defaultMessage: 'View Job'
}
);
interface ViewMlJobArgs { interface ViewMlJobArgs {
serviceName: string; serviceName: string;
transactionType: string; transactionType: string;
@ -36,7 +44,7 @@ export const ViewMLJob: React.SFC<ViewMlJobArgs> = ({
serviceName, serviceName,
transactionType, transactionType,
location, location,
children = 'View Job' children = viewJobLabel
}) => { }) => {
const pathname = '/app/ml'; const pathname = '/app/ml';
const hash = '/timeseriesexplorer'; const hash = '/timeseriesexplorer';