Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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