Skip to content

Commit

Permalink
Feature/translate monitoring access denied (elastic#24985) (elastic#2…
Browse files Browse the repository at this point in the history
…5718)

* Translate monitoring - access_denied

* Translate monitoring - lib, services

* Translate monitoring - common

* Fix issues

* Fix issue
  • Loading branch information
maryia-lapata authored Nov 20, 2018
1 parent a0bd93b commit b953b86
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 46 deletions.
12 changes: 8 additions & 4 deletions x-pack/plugins/monitoring/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { i18n } from '@kbn/i18n';

/**
* Helper string to add as a tag in every logging call
*/
Expand Down Expand Up @@ -129,10 +131,12 @@ export const LOGSTASH = {
}
};

export const DEFAULT_NO_DATA_MESSAGE = 'There are no records that match your query. Try changing the time range selection.';
export const DEFAULT_NO_DATA_MESSAGE_WITH_FILTER = (
'There are no records that match your query with the filter [{{FILTER}}]. Try changing the filter or the time range selection.'
);
export const DEFAULT_NO_DATA_MESSAGE = i18n.translate('xpack.monitoring.defaultNoDataMessage', {
defaultMessage: 'There are no records that match your query. Try changing the time range selection.' });
export const DEFAULT_NO_DATA_MESSAGE_WITH_FILTER = i18n.translate('xpack.monitoring.defaultNoDataWithFilterMessage', {
defaultMessage:
'There are no records that match your query with the filter [{filter}]. Try changing the filter or the time range selection.',
values: { filter: '{{FILTER}}' } });

export const TABLE_ACTION_UPDATE_FILTER = 'UPDATE_FILTER';
export const TABLE_ACTION_RESET_PAGING = 'RESET_PAGING';
Expand Down
24 changes: 20 additions & 4 deletions x-pack/plugins/monitoring/public/lib/ajax_error_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
EuiSpacer,
EuiText,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';

export function formatMonitoringError(err) {
// TODO: We should stop using Boom for errors and instead write a custom handler to return richer error objects
Expand All @@ -24,7 +25,11 @@ export function formatMonitoringError(err) {
{ err.data.message }
</p>
<EuiText size="xs">
HTTP { err.status }
<FormattedMessage
id="xpack.monitoring.ajaxErrorHandler.httpErrorMessage"
defaultMessage="HTTP {errStatus}"
values={{ errStatus: err.status }}
/>
</EuiText>
</EuiText>
);
Expand All @@ -43,7 +48,11 @@ export function ajaxErrorHandlersProvider($injector) {
kbnUrl.redirect('access-denied');
} else if (err.status === 404 && !contains($window.location.hash, 'no-data')) { // pass through if this is a 404 and we're already on the no-data page
toastNotifications.addDanger({
title: 'Monitoring Request Failed',
title: (
<FormattedMessage
id="xpack.monitoring.ajaxErrorHandler.requestFailedNotificationTitle"
defaultMessage="Monitoring Request Failed"
/>),
text: (
<div>
{ formatMonitoringError(err) }
Expand All @@ -53,14 +62,21 @@ export function ajaxErrorHandlersProvider($injector) {
color="danger"
onClick={() => $window.location.reload()}
>
Retry
<FormattedMessage
id="xpack.monitoring.ajaxErrorHandler.requestFailedNotification.retryButtonLabel"
defaultMessage="Retry"
/>
</EuiButton>
</div>
)
});
} else {
toastNotifications.addDanger({
title: 'Monitoring Request Error',
title: (
<FormattedMessage
id="xpack.monitoring.ajaxErrorHandler.requestErrorNotificationTitle"
defaultMessage="Monitoring Request Error"
/>),
text: formatMonitoringError(err)
});
}
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/monitoring/public/lib/format_number.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import moment from 'moment';
import 'moment-duration-format';
import numeral from '@elastic/numeral';
import { i18n } from '@kbn/i18n';

export function formatBytesUsage(used, max) {
return formatNumber(used, 'byte') + ' / ' + formatNumber(max, 'byte');
Expand Down Expand Up @@ -61,5 +62,5 @@ export function formatMetric(value, format, suffix, options = {}) {
}
return formatNumber(value, format) + _suffix;
}
return 'N/A';
return i18n.translate('xpack.monitoring.formatNumbers.notAvailableLabel', { defaultMessage: 'N/A' });
}
10 changes: 7 additions & 3 deletions x-pack/plugins/monitoring/public/register_feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ import chrome from 'ui/chrome';
import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/registry/feature_catalogue';

if (chrome.getInjected('monitoringUiEnabled')) {
FeatureCatalogueRegistryProvider.register(() => {
FeatureCatalogueRegistryProvider.register((i18n) => {
return {
id: 'monitoring',
title: 'Monitoring',
description: 'Track the real-time health and performance of your Elastic Stack.',
title: i18n('xpack.monitoring.monitoringTitle', {
defaultMessage: 'Monitoring'
}),
description: i18n('xpack.monitoring.monitoringDescription', {
defaultMessage: 'Track the real-time health and performance of your Elastic Stack.'
}),
icon: 'monitoringApp',
path: '/app/monitoring',
showOnHomePage: true,
Expand Down
59 changes: 42 additions & 17 deletions x-pack/plugins/monitoring/public/services/breadcrumbs_provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { set as setBreadcrumbs } from 'ui/chrome/services/breadcrumb_state';
import { i18n } from '@kbn/i18n';

// Helper for making objects to use in a link element
const createCrumb = (url, label, testSubj) => {
Expand All @@ -21,14 +22,20 @@ function getElasticsearchBreadcrumbs(mainInstance) {
if (mainInstance.instance) {
breadcrumbs.push(createCrumb('#/elasticsearch', 'Elasticsearch'));
if (mainInstance.name === 'indices') {
breadcrumbs.push(createCrumb('#/elasticsearch/indices', 'Indices', 'breadcrumbEsIndices'));
breadcrumbs.push(createCrumb('#/elasticsearch/indices', i18n.translate(
'xpack.monitoring.breadcrumbs.es.indicesLabel', { defaultMessage: 'Indices' }), 'breadcrumbEsIndices'));
} else if (mainInstance.name === 'nodes') {
breadcrumbs.push(createCrumb('#/elasticsearch/nodes', 'Nodes', 'breadcrumbEsNodes'));
breadcrumbs.push(createCrumb('#/elasticsearch/nodes', i18n.translate(
'xpack.monitoring.breadcrumbs.es.nodesLabel', { defaultMessage: 'Nodes' }), 'breadcrumbEsNodes'));
} else if (mainInstance.name === 'ml') {
// ML Instance (for user later)
breadcrumbs.push(createCrumb('#/elasticsearch/ml_jobs', 'Jobs'));
breadcrumbs.push(createCrumb('#/elasticsearch/ml_jobs', i18n.translate(
'xpack.monitoring.breadcrumbs.es.jobsLabel', { defaultMessage: 'Jobs' })
));
} else if (mainInstance.name === 'ccr_shard') {
breadcrumbs.push(createCrumb('#/elasticsearch/ccr', 'CCR'));
breadcrumbs.push(createCrumb('#/elasticsearch/ccr', i18n.translate(
'xpack.monitoring.breadcrumbs.es.ccrLabel', { defaultMessage: 'CCR' })
));
}
breadcrumbs.push(createCrumb(null, mainInstance.instance));
} else {
Expand All @@ -43,7 +50,9 @@ function getKibanaBreadcrumbs(mainInstance) {
const breadcrumbs = [];
if (mainInstance.instance) {
breadcrumbs.push(createCrumb('#/kibana', 'Kibana'));
breadcrumbs.push(createCrumb('#/kibana/instances', 'Instances'));
breadcrumbs.push(createCrumb('#/kibana/instances', i18n.translate(
'xpack.monitoring.breadcrumbs.kibana.instancesLabel', { defaultMessage: 'Instances' })
));
} else {
// don't link to Overview when we're possibly on Overview or its sibling tabs
breadcrumbs.push(createCrumb(null, 'Kibana'));
Expand All @@ -53,54 +62,70 @@ function getKibanaBreadcrumbs(mainInstance) {

// generate Logstash breadcrumbs
function getLogstashBreadcrumbs(mainInstance) {
const logstashLabel = i18n.translate('xpack.monitoring.breadcrumbs.logstashLabel', { defaultMessage: 'Logstash' });
const breadcrumbs = [];
if (mainInstance.instance) {
breadcrumbs.push(createCrumb('#/logstash', 'Logstash'));
breadcrumbs.push(createCrumb('#/logstash', logstashLabel));
if (mainInstance.name === 'nodes') {
breadcrumbs.push(createCrumb('#/logstash/nodes', 'Nodes'));
breadcrumbs.push(createCrumb('#/logstash/nodes', i18n.translate(
'xpack.monitoring.breadcrumbs.logstash.nodesLabel', { defaultMessage: 'Nodes' })
));
}
breadcrumbs.push(createCrumb(null, mainInstance.instance));
} else if (mainInstance.page === 'pipeline') {
breadcrumbs.push(createCrumb('#/logstash', 'Logstash'));
breadcrumbs.push(createCrumb('#/logstash/pipelines', 'Pipelines'));
breadcrumbs.push(createCrumb('#/logstash', logstashLabel));
breadcrumbs.push(createCrumb('#/logstash/pipelines', i18n.translate(
'xpack.monitoring.breadcrumbs.logstash.pipelinesLabel', { defaultMessage: 'Pipelines' })
));
} else {
// don't link to Overview when we're possibly on Overview or its sibling tabs
breadcrumbs.push(createCrumb(null, 'Logstash'));
breadcrumbs.push(createCrumb(null, logstashLabel));
}

return breadcrumbs;
}

// generate Beats breadcrumbs
function getBeatsBreadcrumbs(mainInstance) {
const beatsLabel = i18n.translate('xpack.monitoring.breadcrumbs.beatsLabel', { defaultMessage: 'Beats' });
const breadcrumbs = [];
if (mainInstance.instance) {
breadcrumbs.push(createCrumb('#/beats', 'Beats'));
breadcrumbs.push(createCrumb('#/beats/beats', 'Instances'));
breadcrumbs.push(createCrumb('#/beats', beatsLabel));
breadcrumbs.push(createCrumb('#/beats/beats', i18n.translate(
'xpack.monitoring.breadcrumbs.beats.instancesLabel', { defaultMessage: 'Instances' })
));
breadcrumbs.push(createCrumb(null, mainInstance.instance));
} else {
breadcrumbs.push(createCrumb(null, 'Beats'));
breadcrumbs.push(createCrumb(null, beatsLabel));
}

return breadcrumbs;
}

// generate Apm breadcrumbs
function getApmBreadcrumbs(mainInstance) {
const apmLabel = i18n.translate('xpack.monitoring.breadcrumbs.apmLabel', { defaultMessage: 'APM' });
const breadcrumbs = [];
if (mainInstance.instance) {
breadcrumbs.push(createCrumb('#/apm', 'APM'));
breadcrumbs.push(createCrumb('#/apm/instances', 'Instances'));
breadcrumbs.push(createCrumb('#/apm', apmLabel));
breadcrumbs.push(createCrumb('#/apm/instances', i18n.translate(
'xpack.monitoring.breadcrumbs.apm.instancesLabel', { defaultMessage: 'Instances' })
));
} else {
// don't link to Overview when we're possibly on Overview or its sibling tabs
breadcrumbs.push(createCrumb(null, 'APM'));
breadcrumbs.push(createCrumb(null, apmLabel));
}
return breadcrumbs;
}

export function breadcrumbsProvider() {
return function createBreadcrumbs(clusterName, mainInstance) {
let breadcrumbs = [ createCrumb('#/home', 'Clusters', 'breadcrumbClusters') ];
let breadcrumbs = [ createCrumb('#/home',
i18n.translate(
'xpack.monitoring.breadcrumbs.clustersLabel', { defaultMessage: 'Clusters' }
),
'breadcrumbClusters')
];

if (!mainInstance.inOverview && clusterName) {
breadcrumbs.push(createCrumb('#/overview', clusterName));
Expand Down
8 changes: 6 additions & 2 deletions x-pack/plugins/monitoring/public/services/title.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ import { uiModules } from 'ui/modules';
import { DocTitleProvider } from 'ui/doc_title';

const uiModule = uiModules.get('monitoring/title', []);
uiModule.service('title', (Private) => {
uiModule.service('title', (Private, i18n) => {
const docTitle = Private(DocTitleProvider);
return function changeTitle(cluster, suffix) {
let clusterName = _.get(cluster, 'cluster_name');
clusterName = (clusterName) ? `- ${clusterName}` : '';
suffix = (suffix) ? `- ${suffix}` : '';
docTitle.change(`Monitoring ${clusterName} ${suffix}`, true);
docTitle.change(
i18n('xpack.monitoring.monitoringDocTitle', {
defaultMessage: 'Monitoring {clusterName} {suffix}',
values: { clusterName, suffix }
}), true);
};
});
38 changes: 23 additions & 15 deletions x-pack/plugins/monitoring/public/views/access_denied/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,40 @@
<div class="kuiInfoPanel kuiInfoPanel--error">
<div class="kuiInfoPanelHeader">
<span class="kuiInfoPanelHeader__icon kuiIcon kuiIcon--error fa-warning"></span>
<span class="kuiInfoPanelHeader__title" data-test-subj="accessDeniedTitle">
Access Denied
</span>
<span
class="kuiInfoPanelHeader__title"
data-test-subj="accessDeniedTitle"
i18n-id="xpack.monitoring.accessDeniedTitle"
i18n-default-message="Access Denied"
></span>
</div>

<div class="kuiInfoPanelBody">
<div class="kuiInfoPanelBody__message">
You are not authorized to access Monitoring. To use Monitoring, you
need the privileges granted by both the `kibana_user` and
`monitoring_user` roles.
</div>
<div
class="kuiInfoPanelBody__message"
i18n-id="xpack.monitoring.accessDenied.notAuthorizedDescription"
i18n-default-message="You are not authorized to access Monitoring. To use Monitoring, you
need the privileges granted by both the `{kibanaUser}` and
`{monitoringUser}` roles."
i18n-values="{ kibanaUser: 'kibana_user', monitoringUser: 'monitoring_user' }"
></div>

<div class="kuiInfoPanelBody__message">
If you are attempting to access a dedicated monitoring cluster, this
<div
class="kuiInfoPanelBody__message"
i18n-id="xpack.monitoring.accessDenied.clusterNotConfiguredDescription"
i18n-default-message="If you are attempting to access a dedicated monitoring cluster, this
might be because you are logged in as a user that is not configured on
the monitoring cluster.
</div>
the monitoring cluster."
></div>

<div class="kuiInfoPanelBody__message">
<div class="kuiButtonGroup">
<button
ng-click="accessDenied.goToKibana();"
class="kuiButton kuiButton--primary"
>
Back to Kibana
</button>
i18n-id="xpack.monitoring.accessDenied.backToKibanaButtonLabel"
i18n-default-message="Back to Kibana"
></button>
</div>
</div>
</div>
Expand Down

0 comments on commit b953b86

Please sign in to comment.