mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[i18n] Translate ML - settings - calendar management (#27839)
* Translate settings -> calendar management * Update snapshots * Update test for calendar form * Minor fix for id name
This commit is contained in:
parent
63999aa7c7
commit
6a455833da
27 changed files with 524 additions and 189 deletions
|
@ -11,7 +11,7 @@ exports[`NewCalendar Renders new calendar form 1`] = `
|
||||||
panelPaddingSize="l"
|
panelPaddingSize="l"
|
||||||
verticalPosition="center"
|
verticalPosition="center"
|
||||||
>
|
>
|
||||||
<CalendarForm
|
<InjectIntl(CalendarForm)
|
||||||
calendarId=""
|
calendarId=""
|
||||||
canCreateCalendar={true}
|
canCreateCalendar={true}
|
||||||
canDeleteCalendar={true}
|
canDeleteCalendar={true}
|
||||||
|
|
|
@ -1,5 +1,28 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`CalendarForm CalendarId shown as title when editing 1`] = `
|
||||||
|
<EuiTitle
|
||||||
|
size="m"
|
||||||
|
textTransform="none"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
className="euiTitle euiTitle--medium"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Calendar {calendarId}"
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.calendarTitle"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"calendarId": "test-calendar",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Calendar test-calendar
|
||||||
|
</FormattedMessage>
|
||||||
|
</h1>
|
||||||
|
</EuiTitle>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`CalendarForm Renders calendar form 1`] = `
|
exports[`CalendarForm Renders calendar form 1`] = `
|
||||||
<EuiForm>
|
<EuiForm>
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
@ -7,14 +30,19 @@ exports[`CalendarForm Renders calendar form 1`] = `
|
||||||
describedByIds={Array []}
|
describedByIds={Array []}
|
||||||
error={
|
error={
|
||||||
Array [
|
Array [
|
||||||
"Use lowercase alphanumerics (a-z and 0-9), hyphens or underscores;
|
"Use lowercase alphanumerics (a-z and 0-9), hyphens or underscores; must start and end with an alphanumeric character",
|
||||||
must start and end with an alphanumeric character",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
fullWidth={false}
|
fullWidth={false}
|
||||||
hasEmptyLabelSpace={false}
|
hasEmptyLabelSpace={false}
|
||||||
isInvalid={true}
|
isInvalid={true}
|
||||||
label="Calendar ID"
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Calendar ID"
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.calendarIdLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<EuiFieldText
|
<EuiFieldText
|
||||||
compressed={false}
|
compressed={false}
|
||||||
|
@ -30,7 +58,13 @@ exports[`CalendarForm Renders calendar form 1`] = `
|
||||||
describedByIds={Array []}
|
describedByIds={Array []}
|
||||||
fullWidth={false}
|
fullWidth={false}
|
||||||
hasEmptyLabelSpace={false}
|
hasEmptyLabelSpace={false}
|
||||||
label="Description"
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Description"
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.descriptionLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<EuiFieldText
|
<EuiFieldText
|
||||||
compressed={false}
|
compressed={false}
|
||||||
|
@ -47,7 +81,13 @@ exports[`CalendarForm Renders calendar form 1`] = `
|
||||||
describedByIds={Array []}
|
describedByIds={Array []}
|
||||||
fullWidth={false}
|
fullWidth={false}
|
||||||
hasEmptyLabelSpace={false}
|
hasEmptyLabelSpace={false}
|
||||||
label="Jobs"
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Jobs"
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.jobsLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<EuiComboBox
|
<EuiComboBox
|
||||||
compressed={false}
|
compressed={false}
|
||||||
|
@ -64,7 +104,13 @@ exports[`CalendarForm Renders calendar form 1`] = `
|
||||||
describedByIds={Array []}
|
describedByIds={Array []}
|
||||||
fullWidth={false}
|
fullWidth={false}
|
||||||
hasEmptyLabelSpace={false}
|
hasEmptyLabelSpace={false}
|
||||||
label="Groups"
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Groups"
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.groupsLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<EuiComboBox
|
<EuiComboBox
|
||||||
compressed={false}
|
compressed={false}
|
||||||
|
@ -85,9 +131,15 @@ exports[`CalendarForm Renders calendar form 1`] = `
|
||||||
describedByIds={Array []}
|
describedByIds={Array []}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
hasEmptyLabelSpace={false}
|
hasEmptyLabelSpace={false}
|
||||||
label="Events"
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Events"
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.eventsLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<EventsTable
|
<InjectIntl(EventsTable)
|
||||||
canCreateCalendar={true}
|
canCreateCalendar={true}
|
||||||
canDeleteCalendar={true}
|
canDeleteCalendar={true}
|
||||||
eventsList={Array []}
|
eventsList={Array []}
|
||||||
|
@ -122,7 +174,11 @@ exports[`CalendarForm Renders calendar form 1`] = `
|
||||||
onClick={[MockFunction]}
|
onClick={[MockFunction]}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Save
|
<FormattedMessage
|
||||||
|
defaultMessage="Save"
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.saveButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem
|
<EuiFlexItem
|
||||||
|
@ -137,7 +193,11 @@ exports[`CalendarForm Renders calendar form 1`] = `
|
||||||
isDisabled={false}
|
isDisabled={false}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Cancel
|
<FormattedMessage
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.cancelButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
|
|
|
@ -25,6 +25,8 @@ import {
|
||||||
import chrome from 'ui/chrome';
|
import chrome from 'ui/chrome';
|
||||||
import { EventsTable } from '../events_table/';
|
import { EventsTable } from '../events_table/';
|
||||||
|
|
||||||
|
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||||
|
|
||||||
|
|
||||||
function EditHeader({
|
function EditHeader({
|
||||||
calendarId,
|
calendarId,
|
||||||
|
@ -33,7 +35,13 @@ function EditHeader({
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<EuiTitle>
|
<EuiTitle>
|
||||||
<h1>Calendar {calendarId}</h1>
|
<h1>
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.calendarTitle"
|
||||||
|
defaultMessage="Calendar {calendarId}"
|
||||||
|
values={{ calendarId }}
|
||||||
|
/>
|
||||||
|
</h1>
|
||||||
</EuiTitle>
|
</EuiTitle>
|
||||||
<EuiText>
|
<EuiText>
|
||||||
<p>
|
<p>
|
||||||
|
@ -45,7 +53,7 @@ function EditHeader({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CalendarForm({
|
export const CalendarForm = injectI18n(function CalendarForm({
|
||||||
calendarId,
|
calendarId,
|
||||||
canCreateCalendar,
|
canCreateCalendar,
|
||||||
canDeleteCalendar,
|
canDeleteCalendar,
|
||||||
|
@ -67,10 +75,14 @@ export function CalendarForm({
|
||||||
saving,
|
saving,
|
||||||
selectedGroupOptions,
|
selectedGroupOptions,
|
||||||
selectedJobOptions,
|
selectedJobOptions,
|
||||||
showNewEventModal
|
showNewEventModal,
|
||||||
|
intl
|
||||||
}) {
|
}) {
|
||||||
const msg = `Use lowercase alphanumerics (a-z and 0-9), hyphens or underscores;
|
const msg = intl.formatMessage({
|
||||||
must start and end with an alphanumeric character`;
|
id: 'xpack.ml.calendarsEdit.calendarForm.allowedCharactersDescription',
|
||||||
|
defaultMessage: 'Use lowercase alphanumerics (a-z and 0-9), hyphens or underscores; ' +
|
||||||
|
'must start and end with an alphanumeric character'
|
||||||
|
});
|
||||||
const helpText = (isNewCalendarIdValid === true && !isEdit) ? msg : undefined;
|
const helpText = (isNewCalendarIdValid === true && !isEdit) ? msg : undefined;
|
||||||
const error = (isNewCalendarIdValid === false && !isEdit) ? [msg] : undefined;
|
const error = (isNewCalendarIdValid === false && !isEdit) ? [msg] : undefined;
|
||||||
const saveButtonDisabled = (canCreateCalendar === false || saving || !isNewCalendarIdValid || calendarId === '');
|
const saveButtonDisabled = (canCreateCalendar === false || saving || !isNewCalendarIdValid || calendarId === '');
|
||||||
|
@ -80,7 +92,10 @@ export function CalendarForm({
|
||||||
{!isEdit &&
|
{!isEdit &&
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
label="Calendar ID"
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.calendarIdLabel"
|
||||||
|
defaultMessage="Calendar ID"
|
||||||
|
/>}
|
||||||
helpText={helpText}
|
helpText={helpText}
|
||||||
error={error}
|
error={error}
|
||||||
isInvalid={!isNewCalendarIdValid}
|
isInvalid={!isNewCalendarIdValid}
|
||||||
|
@ -94,7 +109,10 @@ export function CalendarForm({
|
||||||
</EuiFormRow>
|
</EuiFormRow>
|
||||||
|
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
label="Description"
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.descriptionLabel"
|
||||||
|
defaultMessage="Description"
|
||||||
|
/>}
|
||||||
>
|
>
|
||||||
<EuiFieldText
|
<EuiFieldText
|
||||||
name="description"
|
name="description"
|
||||||
|
@ -111,7 +129,10 @@ export function CalendarForm({
|
||||||
description={description}
|
description={description}
|
||||||
/>}
|
/>}
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
label="Jobs"
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.jobsLabel"
|
||||||
|
defaultMessage="Jobs"
|
||||||
|
/>}
|
||||||
>
|
>
|
||||||
<EuiComboBox
|
<EuiComboBox
|
||||||
options={jobIds}
|
options={jobIds}
|
||||||
|
@ -122,7 +143,10 @@ export function CalendarForm({
|
||||||
</EuiFormRow>
|
</EuiFormRow>
|
||||||
|
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
label="Groups"
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.groupsLabel"
|
||||||
|
defaultMessage="Groups"
|
||||||
|
/>}
|
||||||
>
|
>
|
||||||
<EuiComboBox
|
<EuiComboBox
|
||||||
onCreateOption={onCreateGroupOption}
|
onCreateOption={onCreateGroupOption}
|
||||||
|
@ -136,7 +160,10 @@ export function CalendarForm({
|
||||||
<EuiSpacer size="xl" />
|
<EuiSpacer size="xl" />
|
||||||
|
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
label="Events"
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.eventsLabel"
|
||||||
|
defaultMessage="Events"
|
||||||
|
/>}
|
||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
<EventsTable
|
<EventsTable
|
||||||
|
@ -158,7 +185,13 @@ export function CalendarForm({
|
||||||
onClick={isEdit ? onEdit : onCreate}
|
onClick={isEdit ? onEdit : onCreate}
|
||||||
isDisabled={saveButtonDisabled}
|
isDisabled={saveButtonDisabled}
|
||||||
>
|
>
|
||||||
{saving ? 'Saving...' : 'Save'}
|
{saving ? (<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.savingButtonLabel"
|
||||||
|
defaultMessage="Saving…"
|
||||||
|
/>) : (<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.saveButtonLabel"
|
||||||
|
defaultMessage="Save"
|
||||||
|
/>)}
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
|
@ -166,15 +199,18 @@ export function CalendarForm({
|
||||||
isDisabled={saving}
|
isDisabled={saving}
|
||||||
href={`${chrome.getBasePath()}/app/ml#/settings/calendars_list`}
|
href={`${chrome.getBasePath()}/app/ml#/settings/calendars_list`}
|
||||||
>
|
>
|
||||||
Cancel
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.calendarForm.cancelButtonLabel"
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
</EuiForm>
|
</EuiForm>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
CalendarForm.propTypes = {
|
CalendarForm.WrappedComponent.propTypes = {
|
||||||
calendarId: PropTypes.string.isRequired,
|
calendarId: PropTypes.string.isRequired,
|
||||||
canCreateCalendar: PropTypes.bool.isRequired,
|
canCreateCalendar: PropTypes.bool.isRequired,
|
||||||
canDeleteCalendar: PropTypes.bool.isRequired,
|
canDeleteCalendar: PropTypes.bool.isRequired,
|
||||||
|
|
|
@ -11,7 +11,7 @@ jest.mock('ui/chrome', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CalendarForm } from './calendar_form';
|
import { CalendarForm } from './calendar_form';
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ const testProps = {
|
||||||
describe('CalendarForm', () => {
|
describe('CalendarForm', () => {
|
||||||
|
|
||||||
test('Renders calendar form', () => {
|
test('Renders calendar form', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<CalendarForm {...testProps}/>
|
<CalendarForm.WrappedComponent {...testProps}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
@ -57,16 +57,12 @@ describe('CalendarForm', () => {
|
||||||
calendarId: 'test-calendar',
|
calendarId: 'test-calendar',
|
||||||
description: 'test description',
|
description: 'test description',
|
||||||
};
|
};
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<CalendarForm {...editProps} />
|
<CalendarForm.WrappedComponent {...editProps} />
|
||||||
);
|
);
|
||||||
const calendarId = wrapper.find('EuiTitle');
|
const calendarId = wrapper.find('EuiTitle');
|
||||||
|
|
||||||
expect(
|
expect(calendarId).toMatchSnapshot();
|
||||||
calendarId.containsMatchingElement(
|
|
||||||
<h1>Calendar test-calendar</h1>
|
|
||||||
)
|
|
||||||
).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,6 +20,8 @@ import { getCreateCalendarBreadcrumbs, getEditCalendarBreadcrumbs } from '../../
|
||||||
|
|
||||||
import uiRoutes from 'ui/routes';
|
import uiRoutes from 'ui/routes';
|
||||||
|
|
||||||
|
import { I18nProvider } from '@kbn/i18n/react';
|
||||||
|
|
||||||
const template = `
|
const template = `
|
||||||
<ml-nav-menu name="settings" />
|
<ml-nav-menu name="settings" />
|
||||||
<div class="mlCalendarManagement">
|
<div class="mlCalendarManagement">
|
||||||
|
@ -64,7 +66,9 @@ module.directive('mlNewCalendar', function ($route) {
|
||||||
};
|
};
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement(NewCalendar, props),
|
<I18nProvider>
|
||||||
|
{React.createElement(NewCalendar, props)}
|
||||||
|
</I18nProvider>,
|
||||||
element[0]
|
element[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,11 @@ exports[`EventsTable Renders events table with search bar 1`] = `
|
||||||
size="s"
|
size="s"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
New event
|
<FormattedMessage
|
||||||
|
defaultMessage="New event"
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.newEventButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiButton>,
|
</EuiButton>,
|
||||||
<EuiButton
|
<EuiButton
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -153,7 +157,11 @@ exports[`EventsTable Renders events table with search bar 1`] = `
|
||||||
size="s"
|
size="s"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Import events
|
<FormattedMessage
|
||||||
|
defaultMessage="Import events"
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.importEventsButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiButton>,
|
</EuiButton>,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ import {
|
||||||
EuiSpacer,
|
EuiSpacer,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
|
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||||
|
|
||||||
export const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
|
export const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
|
||||||
|
|
||||||
function DeleteButton({ onClick, canDeleteCalendar }) {
|
function DeleteButton({ onClick, canDeleteCalendar }) {
|
||||||
|
@ -28,20 +30,24 @@ function DeleteButton({ onClick, canDeleteCalendar }) {
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
isDisabled={canDeleteCalendar === false}
|
isDisabled={canDeleteCalendar === false}
|
||||||
>
|
>
|
||||||
Delete
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.deleteButtonLabel"
|
||||||
|
defaultMessage="Delete"
|
||||||
|
/>
|
||||||
</EuiButtonEmpty>
|
</EuiButtonEmpty>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EventsTable({
|
export const EventsTable = injectI18n(function EventsTable({
|
||||||
canCreateCalendar,
|
canCreateCalendar,
|
||||||
canDeleteCalendar,
|
canDeleteCalendar,
|
||||||
eventsList,
|
eventsList,
|
||||||
onDeleteClick,
|
onDeleteClick,
|
||||||
showSearchBar,
|
showSearchBar,
|
||||||
showImportModal,
|
showImportModal,
|
||||||
showNewEventModal
|
showNewEventModal,
|
||||||
|
intl
|
||||||
}) {
|
}) {
|
||||||
const sorting = {
|
const sorting = {
|
||||||
sort: {
|
sort: {
|
||||||
|
@ -58,13 +64,19 @@ export function EventsTable({
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
field: 'description',
|
field: 'description',
|
||||||
name: 'Description',
|
name: intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsEdit.eventsTable.descriptionColumnName',
|
||||||
|
defaultMessage: 'Description'
|
||||||
|
}),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
truncateText: true
|
truncateText: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'start_time',
|
field: 'start_time',
|
||||||
name: 'Start',
|
name: intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsEdit.eventsTable.startColumnName',
|
||||||
|
defaultMessage: 'Start'
|
||||||
|
}),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
render: (timeMs) => {
|
render: (timeMs) => {
|
||||||
const time = moment(timeMs);
|
const time = moment(timeMs);
|
||||||
|
@ -73,7 +85,10 @@ export function EventsTable({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'end_time',
|
field: 'end_time',
|
||||||
name: 'End',
|
name: intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsEdit.eventsTable.endColumnName',
|
||||||
|
defaultMessage: 'End'
|
||||||
|
}),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
render: (timeMs) => {
|
render: (timeMs) => {
|
||||||
const time = moment(timeMs);
|
const time = moment(timeMs);
|
||||||
|
@ -103,7 +118,10 @@ export function EventsTable({
|
||||||
iconType="plusInCircle"
|
iconType="plusInCircle"
|
||||||
onClick={showNewEventModal}
|
onClick={showNewEventModal}
|
||||||
>
|
>
|
||||||
New event
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.newEventButtonLabel"
|
||||||
|
defaultMessage="New event"
|
||||||
|
/>
|
||||||
</EuiButton>),
|
</EuiButton>),
|
||||||
(
|
(
|
||||||
<EuiButton
|
<EuiButton
|
||||||
|
@ -114,7 +132,10 @@ export function EventsTable({
|
||||||
iconType="importAction"
|
iconType="importAction"
|
||||||
onClick={showImportModal}
|
onClick={showImportModal}
|
||||||
>
|
>
|
||||||
Import events
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.importEventsButtonLabel"
|
||||||
|
defaultMessage="Import events"
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
)],
|
)],
|
||||||
box: {
|
box: {
|
||||||
|
@ -136,9 +157,9 @@ export function EventsTable({
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
EventsTable.propTypes = {
|
EventsTable.WrappedComponent.propTypes = {
|
||||||
canCreateCalendar: PropTypes.bool,
|
canCreateCalendar: PropTypes.bool,
|
||||||
canDeleteCalendar: PropTypes.bool,
|
canDeleteCalendar: PropTypes.bool,
|
||||||
eventsList: PropTypes.array.isRequired,
|
eventsList: PropTypes.array.isRequired,
|
||||||
|
@ -148,7 +169,7 @@ EventsTable.propTypes = {
|
||||||
showSearchBar: PropTypes.bool,
|
showSearchBar: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
EventsTable.defaultProps = {
|
EventsTable.WrappedComponent.defaultProps = {
|
||||||
showSearchBar: false,
|
showSearchBar: false,
|
||||||
canCreateCalendar: true,
|
canCreateCalendar: true,
|
||||||
canDeleteCalendar: true
|
canDeleteCalendar: true
|
||||||
|
|
|
@ -11,7 +11,7 @@ jest.mock('ui/chrome', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
import { shallow } from 'enzyme';
|
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EventsTable } from './events_table';
|
import { EventsTable } from './events_table';
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ const testProps = {
|
||||||
describe('EventsTable', () => {
|
describe('EventsTable', () => {
|
||||||
|
|
||||||
test('Renders events table with no search bar', () => {
|
test('Renders events table with no search bar', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<EventsTable {...testProps}/>
|
<EventsTable.WrappedComponent {...testProps}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
@ -46,8 +46,8 @@ describe('EventsTable', () => {
|
||||||
showSearchBar: true,
|
showSearchBar: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<EventsTable {...showSearchBarProps} />
|
<EventsTable.WrappedComponent {...showSearchBarProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
|
|
@ -21,7 +21,11 @@ exports[`ImportModal Renders import modal 1`] = `
|
||||||
grow={false}
|
grow={false}
|
||||||
>
|
>
|
||||||
<EuiModalHeaderTitle>
|
<EuiModalHeaderTitle>
|
||||||
Import events
|
<FormattedMessage
|
||||||
|
defaultMessage="Import events"
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.importEventsTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiModalHeaderTitle>
|
</EuiModalHeaderTitle>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem
|
<EuiFlexItem
|
||||||
|
@ -29,7 +33,11 @@ exports[`ImportModal Renders import modal 1`] = `
|
||||||
grow={false}
|
grow={false}
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
Import events from an ICS file.
|
<FormattedMessage
|
||||||
|
defaultMessage="Import events from an ICS file."
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.importEventsDescription"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</p>
|
</p>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
|
@ -66,7 +74,11 @@ exports[`ImportModal Renders import modal 1`] = `
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Import
|
<FormattedMessage
|
||||||
|
defaultMessage="Import"
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.importButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -74,7 +86,11 @@ exports[`ImportModal Renders import modal 1`] = `
|
||||||
onClick={[MockFunction]}
|
onClick={[MockFunction]}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Cancel
|
<FormattedMessage
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.cancelButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiButtonEmpty>
|
</EuiButtonEmpty>
|
||||||
</EuiModalFooter>
|
</EuiModalFooter>
|
||||||
</EuiModal>
|
</EuiModal>
|
||||||
|
|
|
@ -27,9 +27,16 @@ import {
|
||||||
import { ImportedEvents } from '../imported_events';
|
import { ImportedEvents } from '../imported_events';
|
||||||
import { readFile, parseICSFile, filterEvents } from './utils';
|
import { readFile, parseICSFile, filterEvents } from './utils';
|
||||||
|
|
||||||
|
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||||
|
|
||||||
const MAX_FILE_SIZE_MB = 100;
|
const MAX_FILE_SIZE_MB = 100;
|
||||||
|
|
||||||
export class ImportModal extends Component {
|
export const ImportModal = injectI18n(class ImportModal extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
addImportedEvents: PropTypes.func.isRequired,
|
||||||
|
closeImportModal: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -45,7 +52,10 @@ export class ImportModal extends Component {
|
||||||
|
|
||||||
handleImport = async (loadedFile) => {
|
handleImport = async (loadedFile) => {
|
||||||
const incomingFile = loadedFile[0];
|
const incomingFile = loadedFile[0];
|
||||||
const errorMessage = 'Could not parse ICS file.';
|
const errorMessage = this.props.intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsEdit.importModal.couldNotParseICSFileErrorMessage',
|
||||||
|
defaultMessage: 'Could not parse ICS file.'
|
||||||
|
});
|
||||||
let events = [];
|
let events = [];
|
||||||
|
|
||||||
if (incomingFile && incomingFile.size <= (MAX_FILE_SIZE_MB * 1000000)) {
|
if (incomingFile && incomingFile.size <= (MAX_FILE_SIZE_MB * 1000000)) {
|
||||||
|
@ -107,7 +117,7 @@ export class ImportModal extends Component {
|
||||||
);
|
);
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { closeImportModal } = this.props;
|
const { closeImportModal, intl } = this.props;
|
||||||
const {
|
const {
|
||||||
fileLoading,
|
fileLoading,
|
||||||
fileLoaded,
|
fileLoaded,
|
||||||
|
@ -143,11 +153,19 @@ export class ImportModal extends Component {
|
||||||
>
|
>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiModalHeaderTitle >
|
<EuiModalHeaderTitle >
|
||||||
Import events
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.importEventsTitle"
|
||||||
|
defaultMessage="Import events"
|
||||||
|
/>
|
||||||
</EuiModalHeaderTitle>
|
</EuiModalHeaderTitle>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<p>Import events from an ICS file.</p>
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.importEventsDescription"
|
||||||
|
defaultMessage="Import events from an ICS file."
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
</EuiModalHeader>
|
</EuiModalHeader>
|
||||||
|
@ -157,7 +175,10 @@ export class ImportModal extends Component {
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiFilePicker
|
<EuiFilePicker
|
||||||
compressed
|
compressed
|
||||||
initialPromptText="Select or drag and drop a file"
|
initialPromptText={intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsEdit.importModal.selectOrDragAndDropFilePromptText',
|
||||||
|
defaultMessage: 'Select or drag and drop a file'
|
||||||
|
})}
|
||||||
onChange={this.handleImport}
|
onChange={this.handleImport}
|
||||||
disabled={fileLoading}
|
disabled={fileLoading}
|
||||||
/>
|
/>
|
||||||
|
@ -182,21 +203,22 @@ export class ImportModal extends Component {
|
||||||
fill
|
fill
|
||||||
disabled={fileLoaded === false || errorMessage !== null}
|
disabled={fileLoaded === false || errorMessage !== null}
|
||||||
>
|
>
|
||||||
Import
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.importButtonLabel"
|
||||||
|
defaultMessage="Import"
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
onClick={closeImportModal}
|
onClick={closeImportModal}
|
||||||
>
|
>
|
||||||
Cancel
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.eventsTable.cancelButtonLabel"
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
/>
|
||||||
</EuiButtonEmpty>
|
</EuiButtonEmpty>
|
||||||
</EuiModalFooter>
|
</EuiModalFooter>
|
||||||
</EuiModal>
|
</EuiModal>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
ImportModal.propTypes = {
|
|
||||||
addImportedEvents: PropTypes.func.isRequired,
|
|
||||||
closeImportModal: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ImportModal } from './import_modal';
|
import { ImportModal } from './import_modal';
|
||||||
|
|
||||||
|
@ -34,16 +34,16 @@ const events = [{
|
||||||
describe('ImportModal', () => {
|
describe('ImportModal', () => {
|
||||||
|
|
||||||
test('Renders import modal', () => {
|
test('Renders import modal', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<ImportModal {...testProps}/>
|
<ImportModal.WrappedComponent {...testProps}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Deletes selected event from event table', () => {
|
test('Deletes selected event from event table', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<ImportModal {...testProps} />
|
<ImportModal.WrappedComponent {...testProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const testState = {
|
const testState = {
|
||||||
|
|
|
@ -14,8 +14,15 @@ exports[`ImportedEvents Renders imported events 1`] = `
|
||||||
size="m"
|
size="m"
|
||||||
>
|
>
|
||||||
<h4>
|
<h4>
|
||||||
Events to import:
|
<FormattedMessage
|
||||||
1
|
defaultMessage="Events to import: {eventsCount}"
|
||||||
|
id="xpack.ml.calendarsEdit.importedEvents.eventsToImportTitle"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"eventsCount": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
</h4>
|
</h4>
|
||||||
</EuiText>
|
</EuiText>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
|
@ -23,9 +30,7 @@ exports[`ImportedEvents Renders imported events 1`] = `
|
||||||
component="div"
|
component="div"
|
||||||
grow={false}
|
grow={false}
|
||||||
>
|
>
|
||||||
<EventsTable
|
<InjectIntl(EventsTable)
|
||||||
canCreateCalendar={true}
|
|
||||||
canDeleteCalendar={true}
|
|
||||||
eventsList={
|
eventsList={
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -38,7 +43,6 @@ exports[`ImportedEvents Renders imported events 1`] = `
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
onDeleteClick={[MockFunction]}
|
onDeleteClick={[MockFunction]}
|
||||||
showSearchBar={false}
|
|
||||||
/>
|
/>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiSpacer
|
<EuiSpacer
|
||||||
|
@ -54,7 +58,13 @@ exports[`ImportedEvents Renders imported events 1`] = `
|
||||||
disabled={false}
|
disabled={false}
|
||||||
id="ml-include-past-events"
|
id="ml-include-past-events"
|
||||||
indeterminate={false}
|
indeterminate={false}
|
||||||
label="Include past events"
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Include past events"
|
||||||
|
id="xpack.ml.calendarsEdit.importedEvents.includePastEventsLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
onChange={[MockFunction]}
|
onChange={[MockFunction]}
|
||||||
/>
|
/>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
EuiSpacer
|
EuiSpacer
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { EventsTable } from '../events_table/';
|
import { EventsTable } from '../events_table/';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
|
|
||||||
export function ImportedEvents({
|
export function ImportedEvents({
|
||||||
|
@ -27,10 +28,21 @@ export function ImportedEvents({
|
||||||
<EuiSpacer size="s"/>
|
<EuiSpacer size="s"/>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiText>
|
<EuiText>
|
||||||
<h4>Events to import: {events.length}</h4>
|
<h4>
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.importedEvents.eventsToImportTitle"
|
||||||
|
defaultMessage="Events to import: {eventsCount}"
|
||||||
|
values={{ eventsCount: events.length }}
|
||||||
|
/>
|
||||||
|
</h4>
|
||||||
{showRecurringWarning && (
|
{showRecurringWarning && (
|
||||||
<EuiText color="danger">
|
<EuiText color="danger">
|
||||||
<p>Recurring events not supported. Only the first event will be imported.</p>
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.importedEvents.recurringEventsNotSupportedDescription"
|
||||||
|
defaultMessage="Recurring events not supported. Only the first event will be imported."
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</EuiText>)
|
</EuiText>)
|
||||||
}
|
}
|
||||||
</EuiText>
|
</EuiText>
|
||||||
|
@ -45,7 +57,10 @@ export function ImportedEvents({
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiCheckbox
|
<EuiCheckbox
|
||||||
id="ml-include-past-events"
|
id="ml-include-past-events"
|
||||||
label="Include past events"
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.importedEvents.includePastEventsLabel"
|
||||||
|
defaultMessage="Include past events"
|
||||||
|
/>}
|
||||||
checked={includePastEvents}
|
checked={includePastEvents}
|
||||||
onChange={onCheckboxToggle}
|
onChange={onCheckboxToggle}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -11,7 +11,7 @@ jest.mock('ui/chrome', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
import { shallow } from 'enzyme';
|
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ImportedEvents } from './imported_events';
|
import { ImportedEvents } from './imported_events';
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ const testProps = {
|
||||||
describe('ImportedEvents', () => {
|
describe('ImportedEvents', () => {
|
||||||
|
|
||||||
test('Renders imported events', () => {
|
test('Renders imported events', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<ImportedEvents {...testProps} />
|
<ImportedEvents {...testProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,15 @@ import { ImportModal } from './import_modal';
|
||||||
import { ml } from '../../../services/ml_api_service';
|
import { ml } from '../../../services/ml_api_service';
|
||||||
import { toastNotifications } from 'ui/notify';
|
import { toastNotifications } from 'ui/notify';
|
||||||
|
|
||||||
export class NewCalendar extends Component {
|
import { injectI18n } from '@kbn/i18n/react';
|
||||||
|
|
||||||
|
export const NewCalendar = injectI18n(class NewCalendar extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
calendarId: PropTypes.string,
|
||||||
|
canCreateCalendar: PropTypes.bool.isRequired,
|
||||||
|
canDeleteCalendar: PropTypes.bool.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -99,7 +107,12 @@ export class NewCalendar extends Component {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
toastNotifications.addDanger('An error occurred loading calendar form data. Try refreshing the page.');
|
toastNotifications.addDanger(
|
||||||
|
this.props.intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsEdit.errorWithLoadingCalendarFromDataErrorMessage',
|
||||||
|
defaultMessage: 'An error occurred loading calendar form data. Try refreshing the page.'
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +130,18 @@ export class NewCalendar extends Component {
|
||||||
|
|
||||||
onCreate = async () => {
|
onCreate = async () => {
|
||||||
const { formCalendarId } = this.state;
|
const { formCalendarId } = this.state;
|
||||||
|
const { intl } = this.props;
|
||||||
|
|
||||||
if (this.isDuplicateId()) {
|
if (this.isDuplicateId()) {
|
||||||
toastNotifications.addDanger(`Cannot create calendar with id [${formCalendarId}] as it already exists.`);
|
toastNotifications.addDanger(
|
||||||
|
intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: 'xpack.ml.calendarsEdit.canNotCreateCalendarWithExistingIdErrorMessag',
|
||||||
|
defaultMessage: 'Cannot create calendar with id [{formCalendarId}] as it already exists.'
|
||||||
|
},
|
||||||
|
{ formCalendarId }
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const calendar = this.setUpCalendarForApi();
|
const calendar = this.setUpCalendarForApi();
|
||||||
this.setState({ saving: true });
|
this.setState({ saving: true });
|
||||||
|
@ -130,7 +152,15 @@ export class NewCalendar extends Component {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('Error saving calendar', error);
|
console.log('Error saving calendar', error);
|
||||||
this.setState({ saving: false });
|
this.setState({ saving: false });
|
||||||
toastNotifications.addDanger(`An error occurred creating calendar ${calendar.calendarId}`);
|
toastNotifications.addDanger(
|
||||||
|
intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: 'xpack.ml.calendarsEdit.errorWithCreatingCalendarErrorMessage',
|
||||||
|
defaultMessage: 'An error occurred creating calendar {calendarId}'
|
||||||
|
},
|
||||||
|
{ calendarId: calendar.calendarId }
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +175,15 @@ export class NewCalendar extends Component {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('Error saving calendar', error);
|
console.log('Error saving calendar', error);
|
||||||
this.setState({ saving: false });
|
this.setState({ saving: false });
|
||||||
toastNotifications.addDanger(`An error occurred saving calendar ${calendar.calendarId}. Try refreshing the page.`);
|
toastNotifications.addDanger(
|
||||||
|
this.props.intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: 'xpack.ml.calendarsEdit.errorWithUpdatingCalendarErrorMessage',
|
||||||
|
defaultMessage: 'An error occurred saving calendar {calendarId}. Try refreshing the page.'
|
||||||
|
},
|
||||||
|
{ calendarId: calendar.calendarId }
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,10 +368,4 @@ export class NewCalendar extends Component {
|
||||||
</EuiPage>
|
</EuiPage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
NewCalendar.propTypes = {
|
|
||||||
calendarId: PropTypes.string,
|
|
||||||
canCreateCalendar: PropTypes.bool.isRequired,
|
|
||||||
canDeleteCalendar: PropTypes.bool.isRequired,
|
|
||||||
};
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ jest.mock('./utils', () => ({
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NewCalendar } from './new_calendar';
|
import { NewCalendar } from './new_calendar';
|
||||||
|
|
||||||
|
@ -84,16 +84,16 @@ const props = {
|
||||||
describe('NewCalendar', () => {
|
describe('NewCalendar', () => {
|
||||||
|
|
||||||
test('Renders new calendar form', () => {
|
test('Renders new calendar form', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<NewCalendar {...props}/>
|
<NewCalendar.WrappedComponent {...props}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Import modal shown on Import Events button click', () => {
|
test('Import modal shown on Import Events button click', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<NewCalendar {...props}/>
|
<NewCalendar.WrappedComponent {...props}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const importButton = wrapper.find('[data-testid="ml_import_events"]');
|
const importButton = wrapper.find('[data-testid="ml_import_events"]');
|
||||||
|
@ -104,8 +104,8 @@ describe('NewCalendar', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('New event modal shown on New event button click', () => {
|
test('New event modal shown on New event button click', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<NewCalendar {...props}/>
|
<NewCalendar.WrappedComponent {...props}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const importButton = wrapper.find('[data-testid="ml_new_event"]');
|
const importButton = wrapper.find('[data-testid="ml_new_event"]');
|
||||||
|
@ -116,8 +116,8 @@ describe('NewCalendar', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('isDuplicateId returns true if form calendar id already exists in calendars', () => {
|
test('isDuplicateId returns true if form calendar id already exists in calendars', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<NewCalendar {...props}/>
|
<NewCalendar.WrappedComponent {...props}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const instance = wrapper.instance();
|
const instance = wrapper.instance();
|
||||||
|
@ -135,8 +135,8 @@ describe('NewCalendar', () => {
|
||||||
canCreateCalendar: false,
|
canCreateCalendar: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<NewCalendar {...noCreateProps} />
|
<NewCalendar.WrappedComponent {...noCreateProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const buttons = wrapper.find('[data-testid="ml_save_calendar_button"]');
|
const buttons = wrapper.find('[data-testid="ml_save_calendar_button"]');
|
||||||
|
|
|
@ -31,9 +31,16 @@ import moment from 'moment';
|
||||||
import { TIME_FORMAT } from '../events_table/';
|
import { TIME_FORMAT } from '../events_table/';
|
||||||
import { generateTempId } from '../utils';
|
import { generateTempId } from '../utils';
|
||||||
|
|
||||||
|
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||||
|
|
||||||
const VALID_DATE_STRING_LENGTH = 19;
|
const VALID_DATE_STRING_LENGTH = 19;
|
||||||
|
|
||||||
export class NewEventModal extends Component {
|
export const NewEventModal = injectI18n(class NewEventModal extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
closeModal: PropTypes.func.isRequired,
|
||||||
|
addEvent: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -158,11 +165,19 @@ export class NewEventModal extends Component {
|
||||||
endDateString,
|
endDateString,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
|
const { intl } = this.props;
|
||||||
|
|
||||||
const timeInputs = (
|
const timeInputs = (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<EuiFlexGroup>
|
<EuiFlexGroup>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiFormRow label="From:" helpText={TIME_FORMAT}>
|
<EuiFormRow
|
||||||
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.newEventModal.fromLabel"
|
||||||
|
defaultMessage="From:"
|
||||||
|
/>}
|
||||||
|
helpText={TIME_FORMAT}
|
||||||
|
>
|
||||||
<EuiFieldText
|
<EuiFieldText
|
||||||
name="startTime"
|
name="startTime"
|
||||||
onChange={this.handleTimeStartChange}
|
onChange={this.handleTimeStartChange}
|
||||||
|
@ -172,7 +187,13 @@ export class NewEventModal extends Component {
|
||||||
</EuiFormRow>
|
</EuiFormRow>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiFormRow label="To:" helpText={TIME_FORMAT}>
|
<EuiFormRow
|
||||||
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.newEventModal.toLabel"
|
||||||
|
defaultMessage="To:"
|
||||||
|
/>}
|
||||||
|
helpText={TIME_FORMAT}
|
||||||
|
>
|
||||||
<EuiFieldText
|
<EuiFieldText
|
||||||
name="endTime"
|
name="endTime"
|
||||||
onChange={this.handleTimeEndChange}
|
onChange={this.handleTimeEndChange}
|
||||||
|
@ -203,7 +224,10 @@ export class NewEventModal extends Component {
|
||||||
startDate={startDate}
|
startDate={startDate}
|
||||||
endDate={endDate}
|
endDate={endDate}
|
||||||
isInvalid={startDate > endDate}
|
isInvalid={startDate > endDate}
|
||||||
aria-label="Start date"
|
aria-label={intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsEdit.newEventModal.startDateAriaLabel',
|
||||||
|
defaultMessage: 'Start date'
|
||||||
|
})}
|
||||||
timeFormat={TIME_FORMAT}
|
timeFormat={TIME_FORMAT}
|
||||||
dateFormat={TIME_FORMAT}
|
dateFormat={TIME_FORMAT}
|
||||||
/>
|
/>
|
||||||
|
@ -217,7 +241,10 @@ export class NewEventModal extends Component {
|
||||||
startDate={startDate}
|
startDate={startDate}
|
||||||
endDate={endDate}
|
endDate={endDate}
|
||||||
isInvalid={startDate > endDate}
|
isInvalid={startDate > endDate}
|
||||||
aria-label="End date"
|
aria-label={intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsEdit.newEventModal.endDateAriaLabel',
|
||||||
|
defaultMessage: 'End date'
|
||||||
|
})}
|
||||||
timeFormat={TIME_FORMAT}
|
timeFormat={TIME_FORMAT}
|
||||||
dateFormat={TIME_FORMAT}
|
dateFormat={TIME_FORMAT}
|
||||||
/>
|
/>
|
||||||
|
@ -241,14 +268,20 @@ export class NewEventModal extends Component {
|
||||||
>
|
>
|
||||||
<EuiModalHeader>
|
<EuiModalHeader>
|
||||||
<EuiModalHeaderTitle >
|
<EuiModalHeaderTitle >
|
||||||
Create new event
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.newEventModal.createNewEventTitle"
|
||||||
|
defaultMessage="Create new event"
|
||||||
|
/>
|
||||||
</EuiModalHeaderTitle>
|
</EuiModalHeaderTitle>
|
||||||
</EuiModalHeader>
|
</EuiModalHeader>
|
||||||
|
|
||||||
<EuiModalBody>
|
<EuiModalBody>
|
||||||
<EuiForm>
|
<EuiForm>
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
label="Description"
|
label={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.newEventModal.descriptionLabel"
|
||||||
|
defaultMessage="Description"
|
||||||
|
/>}
|
||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
<EuiFieldText
|
<EuiFieldText
|
||||||
|
@ -269,21 +302,22 @@ export class NewEventModal extends Component {
|
||||||
fill
|
fill
|
||||||
disabled={!description}
|
disabled={!description}
|
||||||
>
|
>
|
||||||
Add
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.newEventModal.addButtonLabel"
|
||||||
|
defaultMessage="Add"
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
onClick={closeModal}
|
onClick={closeModal}
|
||||||
>
|
>
|
||||||
Cancel
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsEdit.newEventModal.cancelButtonLabel"
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
/>
|
||||||
</EuiButtonEmpty>
|
</EuiButtonEmpty>
|
||||||
</EuiModalFooter>
|
</EuiModalFooter>
|
||||||
</EuiModal>
|
</EuiModal>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
NewEventModal.propTypes = {
|
|
||||||
closeModal: PropTypes.func.isRequired,
|
|
||||||
addEvent: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import { shallow } from 'enzyme';
|
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NewEventModal } from './new_event_modal';
|
import { NewEventModal } from './new_event_modal';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
@ -24,8 +24,8 @@ const stateTimestamps = {
|
||||||
describe('NewEventModal', () => {
|
describe('NewEventModal', () => {
|
||||||
|
|
||||||
it('Add button disabled if description empty', () => {
|
it('Add button disabled if description empty', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<NewEventModal {...testProps} />
|
<NewEventModal.WrappedComponent {...testProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const addButton = wrapper.find('EuiButton').first();
|
const addButton = wrapper.find('EuiButton').first();
|
||||||
|
@ -33,7 +33,7 @@ describe('NewEventModal', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('if endDate is less than startDate should set startDate one day before endDate', () => {
|
it('if endDate is less than startDate should set startDate one day before endDate', () => {
|
||||||
const wrapper = shallow(<NewEventModal {...testProps} />);
|
const wrapper = shallowWithIntl(<NewEventModal.WrappedComponent {...testProps} />);
|
||||||
const instance = wrapper.instance();
|
const instance = wrapper.instance();
|
||||||
instance.setState({
|
instance.setState({
|
||||||
startDate: moment(stateTimestamps.startDate),
|
startDate: moment(stateTimestamps.startDate),
|
||||||
|
@ -53,7 +53,7 @@ describe('NewEventModal', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('if startDate is greater than endDate should set endDate one day after startDate', () => {
|
it('if startDate is greater than endDate should set endDate one day after startDate', () => {
|
||||||
const wrapper = shallow(<NewEventModal {...testProps} />);
|
const wrapper = shallowWithIntl(<NewEventModal.WrappedComponent {...testProps} />);
|
||||||
const instance = wrapper.instance();
|
const instance = wrapper.instance();
|
||||||
instance.setState({
|
instance.setState({
|
||||||
startDate: moment(stateTimestamps.startDate),
|
startDate: moment(stateTimestamps.startDate),
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
import { ml } from '../../../services/ml_api_service';
|
import { ml } from '../../../services/ml_api_service';
|
||||||
import { isJobIdValid } from '../../../../common/util/job_utils';
|
import { isJobIdValid } from '../../../../common/util/job_utils';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
|
|
||||||
function getJobIds() {
|
function getJobIds() {
|
||||||
|
@ -17,7 +18,10 @@ function getJobIds() {
|
||||||
resolve(resp.map((job) => job.id));
|
resolve(resp.map((job) => job.id));
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
const errorMessage = `Error fetching job summaries: ${err}`;
|
const errorMessage = i18n.translate('xpack.ml.calendarsEdit.errorWithFetchingJobSummariesErrorMessage', {
|
||||||
|
defaultMessage: 'Error fetching job summaries: {err}',
|
||||||
|
values: { err }
|
||||||
|
});
|
||||||
console.log(errorMessage);
|
console.log(errorMessage);
|
||||||
reject(errorMessage);
|
reject(errorMessage);
|
||||||
});
|
});
|
||||||
|
@ -31,7 +35,10 @@ function getGroupIds() {
|
||||||
resolve(resp.map((group) => group.id));
|
resolve(resp.map((group) => group.id));
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
const errorMessage = `Error loading groups: ${err}`;
|
const errorMessage = i18n.translate('xpack.ml.calendarsEdit.errorWithLoadingGroupsErrorMessage', {
|
||||||
|
defaultMessage: 'Error loading groups: {err}',
|
||||||
|
values: { err }
|
||||||
|
});
|
||||||
console.log(errorMessage);
|
console.log(errorMessage);
|
||||||
reject(errorMessage);
|
reject(errorMessage);
|
||||||
});
|
});
|
||||||
|
@ -45,7 +52,10 @@ function getCalendars() {
|
||||||
resolve(resp);
|
resolve(resp);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
const errorMessage = `Error loading calendars: ${err}`;
|
const errorMessage = i18n.translate('xpack.ml.calendarsEdit.errorWithLoadingCalendarsErrorMessage', {
|
||||||
|
defaultMessage: 'Error loading calendars: {err}',
|
||||||
|
values: { err }
|
||||||
|
});
|
||||||
console.log(errorMessage);
|
console.log(errorMessage);
|
||||||
reject(errorMessage);
|
reject(errorMessage);
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@ exports[`CalendarsList Renders calendar list with calendars 1`] = `
|
||||||
panelPaddingSize="l"
|
panelPaddingSize="l"
|
||||||
verticalPosition="center"
|
verticalPosition="center"
|
||||||
>
|
>
|
||||||
<CalendarsListTable
|
<InjectIntl(CalendarsListTable)
|
||||||
calendarsList={
|
calendarsList={
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
|
|
|
@ -24,8 +24,14 @@ import { ml } from '../../../services/ml_api_service';
|
||||||
import { toastNotifications } from 'ui/notify';
|
import { toastNotifications } from 'ui/notify';
|
||||||
import { mlNodesAvailable } from '../../../ml_nodes_check/check_ml_nodes';
|
import { mlNodesAvailable } from '../../../ml_nodes_check/check_ml_nodes';
|
||||||
import { deleteCalendars } from './delete_calendars';
|
import { deleteCalendars } from './delete_calendars';
|
||||||
|
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||||
|
|
||||||
|
export const CalendarsList = injectI18n(class CalendarsList extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
canCreateCalendar: PropTypes.bool.isRequired,
|
||||||
|
canDeleteCalendar: PropTypes.bool.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export class CalendarsList extends Component {
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -50,7 +56,12 @@ export class CalendarsList extends Component {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
toastNotifications.addDanger('An error occurred loading the list of calendars.');
|
toastNotifications.addDanger(
|
||||||
|
this.props.intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsList.errorWithLoadingListOfCalendarsErrorMessage',
|
||||||
|
defaultMessage: 'An error occurred loading the list of calendars.'
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,20 +111,32 @@ export class CalendarsList extends Component {
|
||||||
destroyModal = (
|
destroyModal = (
|
||||||
<EuiOverlayMask>
|
<EuiOverlayMask>
|
||||||
<EuiConfirmModal
|
<EuiConfirmModal
|
||||||
title="Delete calendar"
|
title={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsList.deleteCalendarsModal.deleteCalendarTitle"
|
||||||
|
defaultMessage="Delete calendar"
|
||||||
|
/>}
|
||||||
onCancel={this.closeDestroyModal}
|
onCancel={this.closeDestroyModal}
|
||||||
onConfirm={this.deleteCalendars}
|
onConfirm={this.deleteCalendars}
|
||||||
cancelButtonText="Cancel"
|
cancelButtonText={<FormattedMessage
|
||||||
confirmButtonText="Delete"
|
id="xpack.ml.calendarsList.deleteCalendarsModal.cancelButtonLabel"
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
/>}
|
||||||
|
confirmButtonText={<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsList.deleteCalendarsModal.deleteButtonLabel"
|
||||||
|
defaultMessage="Delete"
|
||||||
|
/>}
|
||||||
buttonColor="danger"
|
buttonColor="danger"
|
||||||
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
|
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
{
|
<FormattedMessage
|
||||||
`Delete ${selectedForDeletion.length === 1 ? 'this' : 'these'}
|
id="xpack.ml.calendarsList.deleteCalendarsModal.deleteCalendarsDescription"
|
||||||
calendar${selectedForDeletion.length === 1 ? '' : 's'}?
|
defaultMessage="Delete {calendarsCount, plural, one {this calendar} other {these calendars}}? {calendarsList}"
|
||||||
${selectedForDeletion.map((c) => c.calendar_id).join(', ')}`
|
values={{
|
||||||
}
|
calendarsCount: selectedForDeletion.length,
|
||||||
|
calendarsList: (selectedForDeletion.map((c) => c.calendar_id).join(', '))
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</p>
|
</p>
|
||||||
</EuiConfirmModal>
|
</EuiConfirmModal>
|
||||||
</EuiOverlayMask>
|
</EuiOverlayMask>
|
||||||
|
@ -142,9 +165,4 @@ export class CalendarsList extends Component {
|
||||||
</EuiPage>
|
</EuiPage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
CalendarsListTable.propTypes = {
|
|
||||||
canCreateCalendar: PropTypes.bool.isRequired,
|
|
||||||
canDeleteCalendar: PropTypes.bool.isRequired,
|
|
||||||
};
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ jest.mock('../../../services/ml_api_service', () => ({
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ml } from '../../../services/ml_api_service';
|
import { ml } from '../../../services/ml_api_service';
|
||||||
|
|
||||||
|
@ -78,16 +78,16 @@ describe('CalendarsList', () => {
|
||||||
|
|
||||||
test('loads calendars on mount', () => {
|
test('loads calendars on mount', () => {
|
||||||
ml.calendars = jest.fn();
|
ml.calendars = jest.fn();
|
||||||
shallow(
|
shallowWithIntl(
|
||||||
<CalendarsList {...props}/>
|
<CalendarsList.WrappedComponent {...props}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(ml.calendars).toHaveBeenCalled();
|
expect(ml.calendars).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Renders calendar list with calendars', () => {
|
test('Renders calendar list with calendars', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<CalendarsList {...props}/>
|
<CalendarsList.WrappedComponent {...props}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.instance().setState(testingState);
|
wrapper.instance().setState(testingState);
|
||||||
|
@ -96,8 +96,8 @@ describe('CalendarsList', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Sets selected calendars list on checkbox change', () => {
|
test('Sets selected calendars list on checkbox change', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<CalendarsList {...props}/>
|
<CalendarsList.WrappedComponent {...props}/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const instance = wrapper.instance();
|
const instance = wrapper.instance();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
import { toastNotifications } from 'ui/notify';
|
import { toastNotifications } from 'ui/notify';
|
||||||
import { ml } from '../../../services/ml_api_service';
|
import { ml } from '../../../services/ml_api_service';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
|
|
||||||
export async function deleteCalendars(calendarsToDelete, callback) {
|
export async function deleteCalendars(calendarsToDelete, callback) {
|
||||||
|
@ -15,9 +16,17 @@ export async function deleteCalendars(calendarsToDelete, callback) {
|
||||||
|
|
||||||
// Delete each of the specified calendars in turn, waiting for each response
|
// Delete each of the specified calendars in turn, waiting for each response
|
||||||
// before deleting the next to minimize load on the cluster.
|
// before deleting the next to minimize load on the cluster.
|
||||||
const messageId = `${(calendarsToDelete.length > 1) ?
|
const messageId = (calendarsToDelete.length > 1)
|
||||||
`${calendarsToDelete.length} calendars` : calendarsToDelete[0].calendar_id}`;
|
? i18n.translate('xpack.ml.calendarsList.deleteCalendars.calendarsLabel', {
|
||||||
toastNotifications.add(`Deleting ${messageId}`);
|
defaultMessage: '{calendarsToDeleteCount} calendars',
|
||||||
|
values: { calendarsToDeleteCount: calendarsToDelete.length }
|
||||||
|
}) : `${calendarsToDelete[0].calendar_id}`;
|
||||||
|
toastNotifications.add(
|
||||||
|
i18n.translate('xpack.ml.calendarsList.deleteCalendars.deletingCalendarsNotificationMessage', {
|
||||||
|
defaultMessage: 'Deleting {messageId}',
|
||||||
|
values: { messageId }
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
for(const calendar of calendarsToDelete) {
|
for(const calendar of calendarsToDelete) {
|
||||||
const calendarId = calendar.calendar_id;
|
const calendarId = calendar.calendar_id;
|
||||||
|
@ -25,14 +34,22 @@ export async function deleteCalendars(calendarsToDelete, callback) {
|
||||||
await ml.deleteCalendar({ calendarId });
|
await ml.deleteCalendar({ calendarId });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('Error deleting calendar:', error);
|
console.log('Error deleting calendar:', error);
|
||||||
let errorMessage = `An error occurred deleting calendar ${calendar.calendar_id}`;
|
const errorMessage = i18n.translate('xpack.ml.calendarsList.deleteCalendars.deletingCalendarErrorMessage', {
|
||||||
if (error.message) {
|
defaultMessage: 'An error occurred deleting calendar {calendarId}{errorMessage}',
|
||||||
errorMessage += ` : ${error.message}`;
|
values: {
|
||||||
}
|
calendarId: calendar.calendar_id,
|
||||||
|
errorMessage: error.message ? ` : ${error.message}` : ''
|
||||||
|
}
|
||||||
|
});
|
||||||
toastNotifications.addDanger(errorMessage);
|
toastNotifications.addDanger(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toastNotifications.addSuccess(`${messageId} deleted`);
|
toastNotifications.addSuccess(
|
||||||
|
i18n.translate('xpack.ml.calendarsList.deleteCalendars.deletingCalendarSuccessNotificationMessage', {
|
||||||
|
defaultMessage: '{messageId} deleted',
|
||||||
|
values: { messageId }
|
||||||
|
})
|
||||||
|
);
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import { getCalendarManagementBreadcrumbs } from '../../breadcrumbs';
|
||||||
|
|
||||||
import uiRoutes from 'ui/routes';
|
import uiRoutes from 'ui/routes';
|
||||||
|
|
||||||
|
import { I18nProvider } from '@kbn/i18n/react';
|
||||||
|
|
||||||
const template = `
|
const template = `
|
||||||
<ml-nav-menu name="settings" />
|
<ml-nav-menu name="settings" />
|
||||||
<div class="mlCalendarManagement">
|
<div class="mlCalendarManagement">
|
||||||
|
@ -54,7 +56,9 @@ module.directive('mlCalendarsList', function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement(CalendarsList, props),
|
<I18nProvider>
|
||||||
|
{React.createElement(CalendarsList, props)}
|
||||||
|
</I18nProvider>,
|
||||||
element[0]
|
element[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,11 @@ exports[`CalendarsListTable renders the table with all calendars 1`] = `
|
||||||
size="s"
|
size="s"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
New
|
<FormattedMessage
|
||||||
|
defaultMessage="New"
|
||||||
|
id="xpack.ml.calendarsList.table.newButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiButton>,
|
</EuiButton>,
|
||||||
<EuiButton
|
<EuiButton
|
||||||
color="danger"
|
color="danger"
|
||||||
|
@ -88,7 +92,11 @@ exports[`CalendarsListTable renders the table with all calendars 1`] = `
|
||||||
size="s"
|
size="s"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Delete
|
<FormattedMessage
|
||||||
|
defaultMessage="Delete"
|
||||||
|
id="xpack.ml.calendarsList.table.deleteButtonLabel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
</EuiButton>,
|
</EuiButton>,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,10 @@ import {
|
||||||
|
|
||||||
import chrome from 'ui/chrome';
|
import chrome from 'ui/chrome';
|
||||||
|
|
||||||
|
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||||
|
|
||||||
export function CalendarsListTable({
|
|
||||||
|
export const CalendarsListTable = injectI18n(function CalendarsListTable({
|
||||||
calendarsList,
|
calendarsList,
|
||||||
onDeleteClick,
|
onDeleteClick,
|
||||||
setSelectedCalendarList,
|
setSelectedCalendarList,
|
||||||
|
@ -26,7 +28,8 @@ export function CalendarsListTable({
|
||||||
canCreateCalendar,
|
canCreateCalendar,
|
||||||
canDeleteCalendar,
|
canDeleteCalendar,
|
||||||
mlNodesAvailable,
|
mlNodesAvailable,
|
||||||
itemsSelected
|
itemsSelected,
|
||||||
|
intl
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
const sorting = {
|
const sorting = {
|
||||||
|
@ -44,7 +47,10 @@ export function CalendarsListTable({
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
field: 'calendar_id',
|
field: 'calendar_id',
|
||||||
name: 'ID',
|
name: intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsList.table.idColumnName',
|
||||||
|
defaultMessage: 'ID'
|
||||||
|
}),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
truncateText: true,
|
truncateText: true,
|
||||||
render: (id) => (
|
render: (id) => (
|
||||||
|
@ -57,15 +63,27 @@ export function CalendarsListTable({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'job_ids_string',
|
field: 'job_ids_string',
|
||||||
name: 'Jobs',
|
name: intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsList.table.jobsColumnName',
|
||||||
|
defaultMessage: 'Jobs'
|
||||||
|
}),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
truncateText: true,
|
truncateText: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'events_length',
|
field: 'events_length',
|
||||||
name: 'Events',
|
name: intl.formatMessage({
|
||||||
|
id: 'xpack.ml.calendarsList.table.eventsColumnName',
|
||||||
|
defaultMessage: 'Events'
|
||||||
|
}),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
render: (eventsLength) => `${eventsLength} ${eventsLength === 1 ? 'event' : 'events'}`
|
render: (eventsLength) => intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: 'xpack.ml.calendarsList.table.eventsCountLabel',
|
||||||
|
defaultMessage: '{eventsLength, plural, one {# event} other {# events}}'
|
||||||
|
},
|
||||||
|
{ eventsLength }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -83,7 +101,10 @@ export function CalendarsListTable({
|
||||||
href={`${chrome.getBasePath()}/app/ml#/settings/calendars_list/new_calendar`}
|
href={`${chrome.getBasePath()}/app/ml#/settings/calendars_list/new_calendar`}
|
||||||
isDisabled={(canCreateCalendar === false || mlNodesAvailable === false)}
|
isDisabled={(canCreateCalendar === false || mlNodesAvailable === false)}
|
||||||
>
|
>
|
||||||
New
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsList.table.newButtonLabel"
|
||||||
|
defaultMessage="New"
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -94,7 +115,10 @@ export function CalendarsListTable({
|
||||||
onClick={onDeleteClick}
|
onClick={onDeleteClick}
|
||||||
isDisabled={(canDeleteCalendar === false || mlNodesAvailable === false || itemsSelected === false)}
|
isDisabled={(canDeleteCalendar === false || mlNodesAvailable === false || itemsSelected === false)}
|
||||||
>
|
>
|
||||||
Delete
|
<FormattedMessage
|
||||||
|
id="xpack.ml.calendarsList.table.deleteButtonLabel"
|
||||||
|
defaultMessage="Delete"
|
||||||
|
/>
|
||||||
</EuiButton>
|
</EuiButton>
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -119,9 +143,9 @@ export function CalendarsListTable({
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
CalendarsListTable.propTypes = {
|
CalendarsListTable.WrappedComponent.propTypes = {
|
||||||
calendarsList: PropTypes.array.isRequired,
|
calendarsList: PropTypes.array.isRequired,
|
||||||
onDeleteClick: PropTypes.func.isRequired,
|
onDeleteClick: PropTypes.func.isRequired,
|
||||||
loading: PropTypes.bool.isRequired,
|
loading: PropTypes.bool.isRequired,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { CalendarsListTable } from './table';
|
import { CalendarsListTable } from './table';
|
||||||
|
@ -41,15 +41,15 @@ const props = {
|
||||||
describe('CalendarsListTable', () => {
|
describe('CalendarsListTable', () => {
|
||||||
|
|
||||||
test('renders the table with all calendars', () => {
|
test('renders the table with all calendars', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallowWithIntl(
|
||||||
<CalendarsListTable {...props} />
|
<CalendarsListTable.WrappedComponent {...props} />
|
||||||
);
|
);
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('New button enabled if permission available', () => {
|
test('New button enabled if permission available', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<CalendarsListTable {...props} />
|
<CalendarsListTable.WrappedComponent {...props} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const buttons = wrapper.find('[data-testid="new_calendar_button"]');
|
const buttons = wrapper.find('[data-testid="new_calendar_button"]');
|
||||||
|
@ -64,8 +64,8 @@ describe('CalendarsListTable', () => {
|
||||||
canCreateCalendar: false
|
canCreateCalendar: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<CalendarsListTable {...disableProps} />
|
<CalendarsListTable.WrappedComponent {...disableProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const buttons = wrapper.find('[data-testid="new_calendar_button"]');
|
const buttons = wrapper.find('[data-testid="new_calendar_button"]');
|
||||||
|
@ -81,8 +81,8 @@ describe('CalendarsListTable', () => {
|
||||||
mlNodesAvailable: false
|
mlNodesAvailable: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mountWithIntl(
|
||||||
<CalendarsListTable {...disableProps} />
|
<CalendarsListTable.WrappedComponent {...disableProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const buttons = wrapper.find('[data-testid="new_calendar_button"]');
|
const buttons = wrapper.find('[data-testid="new_calendar_button"]');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue