[i18n] APM translations (Part 1) (#27384)
* Translation for APM utils, intex.js and register_feature.js * Fix a typo
This commit is contained in:
parent
d19cafb397
commit
d555241ca7
|
@ -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",
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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';
|
||||||
|
|
Loading…
Reference in a new issue