Skip to content

Commit

Permalink
Feature/dashboard translations (#24328)
Browse files Browse the repository at this point in the history
add dashboard translations
  • Loading branch information
pavel06081991 authored Nov 20, 2018
1 parent 992daf5 commit 7baea1d
Show file tree
Hide file tree
Showing 49 changed files with 860 additions and 261 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ exports[`is rendered 1`] = `
class="dshExitFullScreenButton__text"
data-test-subj="exitFullScreenModeText"
>
Exit full screen
Exit full screen
<span
class="kuiIcon fa fa-angle-left"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import chrome from 'ui/chrome';
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';

import {
KuiButton,
Expand All @@ -30,7 +31,7 @@ import {
EuiScreenReaderOnly,
} from '@elastic/eui';

export class ExitFullScreenButton extends PureComponent {
class ExitFullScreenButtonUi extends PureComponent {

onKeyDown = (e) => {
if (e.keyCode === keyCodes.ESCAPE) {
Expand All @@ -49,25 +50,37 @@ export class ExitFullScreenButton extends PureComponent {
}

render() {
const { intl } = this.props;

return (
<div>
<EuiScreenReaderOnly>
<p aria-live="polite">
In full screen mode, press ESC to exit.
<FormattedMessage
id="kbn.dashboard.exitFullScreenButton.fullScreenModeDescription"
defaultMessage="In full screen mode, press ESC to exit."
/>
</p>
</EuiScreenReaderOnly>
<div
className="dshExitFullScreenButton"
>
<KuiButton
type="hollow"
aria-label="Exit full screen mode"
aria-label={intl.formatMessage({
id: 'kbn.dashboard.exitFullScreenButton.exitFullScreenModeButtonAreaLabel',
defaultMessage: 'Exit full screen mode',
})}
className="dshExitFullScreenButton__mode"
onClick={this.props.onExitFullScreenMode}
>
<span className="dshExitFullScreenButton__logo" data-test-subj="exitFullScreenModeLogo"/>
<span className="dshExitFullScreenButton__text" data-test-subj="exitFullScreenModeText">
Exit full screen <span className="kuiIcon fa fa-angle-left"/>
<FormattedMessage
id="kbn.dashboard.exitFullScreenButton.exitFullScreenModeButtonLabel"
defaultMessage="Exit full screen"
/>
<span className="kuiIcon fa fa-angle-left"/>
</span>
</KuiButton>
</div>
Expand All @@ -76,6 +89,8 @@ export class ExitFullScreenButton extends PureComponent {
}
}

ExitFullScreenButton.propTypes = {
ExitFullScreenButtonUi.propTypes = {
onExitFullScreenMode: PropTypes.func.isRequired,
};

export const ExitFullScreenButton = injectI18n(ExitFullScreenButtonUi);
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jest.mock('ui/chrome',
}), { virtual: true });

import React from 'react';
import { render, mount } from 'enzyme';
import { mountWithIntl, renderWithIntl } from 'test_utils/enzyme_helpers';
import sinon from 'sinon';
import chrome from 'ui/chrome';

Expand All @@ -36,8 +36,8 @@ import { keyCodes } from '@elastic/eui';


test('is rendered', () => {
const component = render(
<ExitFullScreenButton onExitFullScreenMode={() => {}}/>
const component = renderWithIntl(
<ExitFullScreenButton.WrappedComponent onExitFullScreenMode={() => {}}/>
);

expect(component)
Expand All @@ -48,8 +48,8 @@ describe('onExitFullScreenMode', () => {
test('is called when the button is pressed', () => {
const onExitHandler = sinon.stub();

const component = mount(
<ExitFullScreenButton onExitFullScreenMode={onExitHandler} />
const component = mountWithIntl(
<ExitFullScreenButton.WrappedComponent onExitFullScreenMode={onExitHandler} />
);

component.find('button').simulate('click');
Expand All @@ -60,7 +60,7 @@ describe('onExitFullScreenMode', () => {
test('is called when the ESC key is pressed', () => {
const onExitHandler = sinon.stub();

mount(<ExitFullScreenButton onExitFullScreenMode={onExitHandler} />);
mountWithIntl(<ExitFullScreenButton.WrappedComponent onExitFullScreenMode={onExitHandler} />);

const escapeKeyEvent = new KeyboardEvent('keydown', { keyCode: keyCodes.ESCAPE });
document.dispatchEvent(escapeKeyEvent);
Expand All @@ -73,8 +73,8 @@ describe('chrome.setVisible', () => {
test('is called with false when the component is rendered', () => {
chrome.setVisible = sinon.stub();

const component = mount(
<ExitFullScreenButton onExitFullScreenMode={() => {}} />
const component = mountWithIntl(
<ExitFullScreenButton.WrappedComponent onExitFullScreenMode={() => {}} />
);

component.find('button').simulate('click');
Expand All @@ -84,8 +84,8 @@ describe('chrome.setVisible', () => {
});

test('is called with true the component is unmounted', () => {
const component = mount(
<ExitFullScreenButton onExitFullScreenMode={() => {}} />
const component = mountWithIntl(
<ExitFullScreenButton.WrappedComponent onExitFullScreenMode={() => {}} />
);

chrome.setVisible = sinon.stub();
Expand Down
63 changes: 55 additions & 8 deletions src/core_plugins/kibana/public/dashboard/dashboard_app.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
aria-level="1"
ng-if="showPluginBreadcrumbs">
<div class="kuiLocalBreadcrumb">
<a class="kuiLocalBreadcrumb__link" href="{{landingPageUrl()}}">Dashboard</a>
<a
class="kuiLocalBreadcrumb__link"
href="{{landingPageUrl()}}"
i18n-id="kbn.dashboard.dashboardLinkLabel"
i18n-default-message="Dashboard"
></a>
</div>
<div class="kuiLocalBreadcrumb">
{{ getDashTitle() }}
Expand Down Expand Up @@ -46,22 +51,64 @@
ng-show="getShouldShowEditHelp()"
class="dshStartScreen"
>
<h2 class="kuiTitle kuiVerticalRhythm">
This dashboard is empty. Let&rsquo;s fill it up!
<h2
class="kuiTitle kuiVerticalRhythm"
i18n-id="kbn.dashboard.fillDashboardTitle"
i18n-default-message="This dashboard is empty. Let&rsquo;s fill it up!"
>
</h2>

<p class="kuiText kuiVerticalRhythm">
Click the <a kbn-accessible-click class="kuiButton kuiButton--primary kuiButton--small" ng-click="showAddPanel()" aria-label="Add visualization" data-test-subj="emptyDashboardAddPanelButton">Add</a> button in the menu bar above to add a visualization to the dashboard. <br/>If you haven't set up any visualizations yet, <a class="kuiLink" href="#/visualize">visit the Visualize app</a> to create your first visualization.
<p>
<span
i18n-id="kbn.dashboard.addVisualizationDescription1"
i18n-default-message="Click the "
i18n-context="Part of composite label kbn.dashboard.addVisualizationDescription1 + kbn.dashboard.addVisualizationLinkText + kbn.dashboard.addVisualizationDescription2"
></span>
<a
kbn-accessible-click
class="kuiButton kuiButton--primary kuiButton--small"
ng-click="showAddPanel()"
aria-label="{{::'kbn.dashboard.addVisualizationLinkAriaLabel' | i18n: { defaultMessage: 'Add visualization' } }}"
data-test-subj="emptyDashboardAddPanelButton"
i18n-id="kbn.dashboard.addVisualizationLinkText"
i18n-default-message="Add"
></a>
<span
i18n-id="kbn.dashboard.addVisualizationDescription2"
i18n-default-message=" button in the menu bar above to add a visualization to the dashboard. {br}If you haven't set up any visualizations yet, {visitVisualizeAppLink} to create your first visualization."
i18n-values="{
br: '<br/>',
visitVisualizeAppLink: '<a class=\'kuiLink\' href=\'#/visualize\'>' + visitVisualizeAppLinkText + '</a>'
}"
></span>
</p>
</div>

<div ng-show="getShouldShowViewHelp()" class="dshStartScreen">
<h2 class="kuiTitle kuiVerticalRhythm">
This dashboard is empty. Let&rsquo;s fill it up!
<h2
class="kuiTitle kuiVerticalRhythm"
i18n-id="kbn.dashboard.fillDashboardTitle"
i18n-default-message="This dashboard is empty. Let&rsquo;s fill it up!"
>
</h2>

<p class="kuiText kuiVerticalRhythm">
Click the <a kbn-accessible-click class="kuiButton kuiButton--primary kuiButton--small" ng-click="enterEditMode()">Edit</a> button in the menu bar above to start working on your new dashboard.
<span
i18n-id="kbn.dashboard.howToStartWorkingOnNewDashboardDescription1"
i18n-default-message="Click the "
i18n-context="Part of composite label kbn.dashboard.howToStartWorkingOnNewDashboardDescription1 + kbn.dashboard.howToStartWorkingOnNewDashboardEditLinkText + kbn.dashboard.howToStartWorkingOnNewDashboardDescription2"
></span>
<a
kbn-accessible-click
class="kuiButton kuiButton--primary kuiButton--small"
ng-click="enterEditMode()"
i18n-id="kbn.dashboard.howToStartWorkingOnNewDashboardEditLinkText"
i18n-default-message="Edit"
></a>
<span
i18n-id="kbn.dashboard.howToStartWorkingOnNewDashboardDescription2"
i18n-default-message=" button in the menu bar above to start working on your new dashboard."
></span>
</p>
</div>

Expand Down
39 changes: 30 additions & 9 deletions src/core_plugins/kibana/public/dashboard/dashboard_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ import { timefilter } from 'ui/timefilter';
import { getUnhashableStatesProvider } from 'ui/state_management/state_hashing';

import { DashboardViewportProvider } from './viewport/dashboard_viewport_provider';
import { i18n } from '@kbn/i18n';

const app = uiModules.get('app/dashboard', [
'elasticsearch',
Expand Down Expand Up @@ -90,7 +89,8 @@ app.directive('dashboardApp', function ($injector) {
getAppState,
dashboardConfig,
localStorage,
breadcrumbState
breadcrumbState,
i18n,
) {
const filterManager = Private(FilterManagerProvider);
const filterBar = Private(FilterBarQueryFilterProvider);
Expand Down Expand Up @@ -184,7 +184,7 @@ app.directive('dashboardApp', function ($injector) {
const updateBreadcrumbs = () => {
breadcrumbState.set([
{
text: i18n.translate('kbn.dashboard.dashboardAppBreadcrumbsTitle', {
text: i18n('kbn.dashboard.dashboardAppBreadcrumbsTitle', {
defaultMessage: 'Dashboard',
}),
href: $scope.landingPageUrl()
Expand Down Expand Up @@ -273,14 +273,22 @@ app.directive('dashboardApp', function ($injector) {
}

confirmModal(
`Once you discard your changes, there's no getting them back.`,
i18n('kbn.dashboard.changeViewModeConfirmModal.discardChangesDescription',
{ defaultMessage: `Once you discard your changes, there's no getting them back.` }
),
{
onConfirm: revertChangesAndExitEditMode,
onCancel: _.noop,
confirmButtonText: 'Discard changes',
cancelButtonText: 'Continue editing',
confirmButtonText: i18n('kbn.dashboard.changeViewModeConfirmModal.confirmButtonLabel',
{ defaultMessage: 'Discard changes' }
),
cancelButtonText: i18n('kbn.dashboard.changeViewModeConfirmModal.cancelButtonLabel',
{ defaultMessage: 'Continue editing' }
),
defaultFocusedButton: ConfirmationButtonTypes.CANCEL,
title: 'Discard changes to dashboard?'
title: i18n('kbn.dashboard.changeViewModeConfirmModal.discardChangesTitle',
{ defaultMessage: 'Discard changes to dashboard?' }
)
}
);
};
Expand All @@ -302,7 +310,12 @@ app.directive('dashboardApp', function ($injector) {
.then(function (id) {
if (id) {
toastNotifications.addSuccess({
title: `Dashboard '${dash.title}' was saved`,
title: i18n('kbn.dashboard.dashboardWasSavedSuccessMessage',
{
defaultMessage: `Dashboard '{dashTitle}' was saved`,
values: { dashTitle: dash.title },
},
),
'data-test-subj': 'saveDashboardSuccess',
});

Expand All @@ -316,7 +329,15 @@ app.directive('dashboardApp', function ($injector) {
return { id };
}).catch((error) => {
toastNotifications.addDanger({
title: `Dashboard '${dash.title}' was not saved. Error: ${error.message}`,
title: i18n('kbn.dashboard.dashboardWasNotSavedDangerMessage',
{
defaultMessage: `Dashboard '{dashTitle}' was not saved. Error: {errorMessage}`,
values: {
dashTitle: dash.title,
errorMessage: error.message,
},
},
),
'data-test-subj': 'saveDashboardFailure',
});
return { error };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

import { i18n } from '@kbn/i18n';
import _ from 'lodash';
import moment from 'moment';

Expand Down Expand Up @@ -550,7 +551,9 @@ export class DashboardStateManager {
*/
syncTimefilterWithDashboard(timeFilter, quickTimeRanges) {
if (!this.getIsTimeSavedWithDashboard()) {
throw new Error('The time is not saved with this dashboard so should not be synced.');
throw new Error(i18n.translate('kbn.dashboard.stateManager.timeNotSavedWithDashboardErrorMessage', {
defaultMessage: 'The time is not saved with this dashboard so should not be synced.',
}));
}

let mode;
Expand Down
22 changes: 17 additions & 5 deletions src/core_plugins/kibana/public/dashboard/dashboard_strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

import { i18n } from '@kbn/i18n';
import { DashboardViewMode } from './dashboard_view_mode';

/**
Expand All @@ -28,10 +29,21 @@ import { DashboardViewMode } from './dashboard_view_mode';
*/
export function getDashboardTitle(title, viewMode, isDirty) {
const isEditMode = viewMode === DashboardViewMode.EDIT;
const unsavedSuffix = isEditMode && isDirty
? ' (unsaved)'
: '';
let displayTitle;

const displayTitle = `${title}${unsavedSuffix}`;
return isEditMode ? 'Editing ' + displayTitle : displayTitle;
if (isEditMode && isDirty) {
displayTitle = i18n.translate('kbn.dashboard.strings.dashboardUnsavedEditTitle', {
defaultMessage: 'Editing {title} (unsaved)',
values: { title },
});
} else if (isEditMode) {
displayTitle = i18n.translate('kbn.dashboard.strings.dashboardEditTitle', {
defaultMessage: 'Editing {title}',
values: { title },
});
} else {
displayTitle = title;
}

return displayTitle;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ exports[`renders DashboardGrid 1`] = `
}
}
>
<Connect(DashboardPanel)
<Connect(InjectIntl(DashboardPanelUi))
embeddableFactory={
Object {
"create": [MockFunction],
Expand All @@ -53,7 +53,7 @@ exports[`renders DashboardGrid 1`] = `
}
}
>
<Connect(DashboardPanel)
<Connect(InjectIntl(DashboardPanelUi))
embeddableFactory={
Object {
"create": [MockFunction],
Expand Down
Loading

0 comments on commit 7baea1d

Please sign in to comment.