mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
parent
5c506e8615
commit
6f81bd37db
18 changed files with 540 additions and 83 deletions
|
@ -6,26 +6,42 @@ exports[`PipelinesTable component renders component as expected 1`] = `
|
|||
Array [
|
||||
Object {
|
||||
"field": "id",
|
||||
"name": "Id",
|
||||
"name": <FormattedMessage
|
||||
defaultMessage="Id"
|
||||
id="xpack.logstash.pipelinesTable.idColumnLabel"
|
||||
values={Object {}}
|
||||
/>,
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"field": "description",
|
||||
"name": "Description",
|
||||
"name": <FormattedMessage
|
||||
defaultMessage="Description"
|
||||
id="xpack.logstash.pipelinesTable.descriptionColumnLabel"
|
||||
values={Object {}}
|
||||
/>,
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
"truncateText": true,
|
||||
},
|
||||
Object {
|
||||
"field": "lastModifiedHumanized",
|
||||
"name": "Last Modified",
|
||||
"name": <FormattedMessage
|
||||
defaultMessage="Last Modified"
|
||||
id="xpack.logstash.pipelinesTable.lastModifiedColumnLabel"
|
||||
values={Object {}}
|
||||
/>,
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"field": "username",
|
||||
"name": "Modified By",
|
||||
"name": <FormattedMessage
|
||||
defaultMessage="Modified By"
|
||||
id="xpack.logstash.pipelinesTable.modifiedByColumnLabel"
|
||||
values={Object {}}
|
||||
/>,
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
|
@ -73,7 +89,11 @@ exports[`PipelinesTable component renders component as expected 1`] = `
|
|||
Object {
|
||||
"field": "id",
|
||||
"multiSelect": false,
|
||||
"name": "Filter by ID",
|
||||
"name": <FormattedMessage
|
||||
defaultMessage="Filter by ID"
|
||||
id="xpack.logstash.pipelinesTable.filterByIdLabel"
|
||||
values={Object {}}
|
||||
/>,
|
||||
"options": Array [
|
||||
Object {
|
||||
"name": "testPipeline",
|
||||
|
@ -94,7 +114,11 @@ exports[`PipelinesTable component renders component as expected 1`] = `
|
|||
onClick={[MockFunction]}
|
||||
type="button"
|
||||
>
|
||||
Create pipeline
|
||||
<FormattedMessage
|
||||
defaultMessage="Create pipeline"
|
||||
id="xpack.logstash.pipelinesTable.createPipelineButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import pluralize from 'pluralize';
|
||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
EuiCallOut,
|
||||
|
@ -19,7 +19,7 @@ import { InfoAlerts } from './info_alerts';
|
|||
import { PipelinesTable } from './pipelines_table';
|
||||
import { ConfirmDeleteModal } from './confirm_delete_modal';
|
||||
|
||||
export class PipelineList extends React.Component {
|
||||
class PipelineListUi extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -50,28 +50,55 @@ export class PipelineList extends React.Component {
|
|||
|
||||
getEmptyPrompt = () => (
|
||||
<EuiEmptyPrompt
|
||||
title={<h2>No pipelines</h2>}
|
||||
title={(
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelineList.noPipelinesTitle"
|
||||
defaultMessage="No pipelines"
|
||||
/>
|
||||
</h2>
|
||||
)}
|
||||
titleSize="xs"
|
||||
body="There are no pipelines defined."
|
||||
body={(
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelineList.noPipelinesDescription"
|
||||
defaultMessage="There are no pipelines defined."
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
getErrorPrompt = () => (
|
||||
<EuiEmptyPrompt
|
||||
title={<h2>Error</h2>}
|
||||
title={(
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelineList.pipelinesLoadingErrorTitle"
|
||||
defaultMessage="Error"
|
||||
/>
|
||||
</h2>
|
||||
)}
|
||||
titleSize="xs"
|
||||
body="Error encountered while loading pipelines."
|
||||
body={(
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelineList.pipelinesLoadingErrorDescription"
|
||||
defaultMessage="Error encountered while loading pipelines."
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
loadPipelines = () => {
|
||||
const { isReadOnly, licenseService, pipelinesService, toastNotifications } = this.props;
|
||||
const { isReadOnly, licenseService, pipelinesService, toastNotifications, intl } = this.props;
|
||||
|
||||
this.setState({
|
||||
message: (
|
||||
<div>
|
||||
<EuiLoadingSpinner size="m" />
|
||||
Loading pipelines....
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelineList.pipelinesLoadingMessage"
|
||||
defaultMessage="Loading pipelines…"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
|
@ -110,7 +137,12 @@ export class PipelineList extends React.Component {
|
|||
}
|
||||
} else {
|
||||
this.setState({ isForbidden: false });
|
||||
toastNotifications.addDanger(`Couldn't load pipeline. Error: "${err.statusText}".`);
|
||||
toastNotifications.addDanger(intl.formatMessage({
|
||||
id: 'xpack.logstash.pipelineList.pipelineLoadingErrorNotification',
|
||||
defaultMessage: `Couldn't load pipeline. Error: "{errStatusText}".`
|
||||
}, {
|
||||
errStatusText: err.statusText,
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -133,9 +165,19 @@ export class PipelineList extends React.Component {
|
|||
<EuiCallOut
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
title="You do not have permission to manage Logstash pipelines."
|
||||
title={(
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelineList.noPermissionToManageTitle"
|
||||
defaultMessage="You do not have permission to manage Logstash pipelines."
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<p>Please contact your administrator.</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelineList.noPermissionToManageDescription"
|
||||
defaultMessage="Please contact your administrator."
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
) : null;
|
||||
};
|
||||
|
@ -158,32 +200,54 @@ export class PipelineList extends React.Component {
|
|||
|
||||
deleteSelectedPipelines = () => {
|
||||
this.hideDeletePipelinesModal();
|
||||
const { licenseService, pipelinesService, toastNotifications } = this.props;
|
||||
const { licenseService, pipelinesService, toastNotifications, intl } = this.props;
|
||||
const { selection } = this.state;
|
||||
const numPipelinesSelected = selection.length;
|
||||
const totalPluralized = pluralize('Pipeline', numPipelinesSelected);
|
||||
|
||||
const pipelineIds = selection.map(({ id }) => id);
|
||||
return pipelinesService
|
||||
.deletePipelines(pipelineIds)
|
||||
.then(results => {
|
||||
const { numSuccesses, numErrors } = results;
|
||||
const errorPluralized = pluralize('Pipeline', numErrors);
|
||||
|
||||
if (numSuccesses === 1 && numErrors === 0) {
|
||||
toastNotifications.addSuccess(`Deleted "${selection[0].id}"`);
|
||||
toastNotifications.addSuccess(intl.formatMessage({
|
||||
id: 'xpack.logstash.pipelineList.pipelinesSuccessfullyDeletedNotification',
|
||||
defaultMessage: 'Deleted "{id}"',
|
||||
}, {
|
||||
id: selection[0].id,
|
||||
}));
|
||||
} else if (numSuccesses) {
|
||||
let text;
|
||||
if (numErrors) {
|
||||
text = `But ${numErrors} ${errorPluralized} couldn't be deleted.`;
|
||||
text = intl.formatMessage({
|
||||
id: 'xpack.logstash.pipelineList.pipelinesCouldNotBeDeletedDescription',
|
||||
defaultMessage: `But {numErrors, plural, one {# Pipeline} other {# Pipelines}} couldn't be deleted.`,
|
||||
}, {
|
||||
numErrors,
|
||||
});
|
||||
}
|
||||
|
||||
toastNotifications.addSuccess({
|
||||
title: `Deleted ${numSuccesses} out of ${numPipelinesSelected} ${totalPluralized}`,
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.logstash.pipelineList.successfullyDeletedPipelinesNotification',
|
||||
defaultMessage:
|
||||
'Deleted {numSuccesses} out of {numPipelinesSelected, plural, one {# Pipeline} other {# Pipelines}}',
|
||||
}, {
|
||||
numSuccesses,
|
||||
numPipelinesSelected,
|
||||
numPipelinesSelected,
|
||||
}),
|
||||
text,
|
||||
});
|
||||
} else if (numErrors) {
|
||||
toastNotifications.addError(`Failed to delete ${numErrors} ${errorPluralized}`);
|
||||
toastNotifications.addError(intl.formatMessage({
|
||||
id: 'xpack.logstash.pipelineList.couldNotDeletePipelinesNotification',
|
||||
defaultMessage:
|
||||
'Failed to delete {numErrors, plural, one {# Pipeline} other {# Pipelines}}',
|
||||
}, {
|
||||
numErrors,
|
||||
}));
|
||||
}
|
||||
|
||||
this.loadPipelines();
|
||||
|
@ -233,3 +297,5 @@ export class PipelineList extends React.Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const PipelineList = injectI18n(PipelineListUi);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { PipelineList } from './pipeline_list';
|
||||
|
||||
describe('PipelineList component', () => {
|
||||
|
@ -54,7 +54,7 @@ describe('PipelineList component', () => {
|
|||
});
|
||||
|
||||
async function renderWithProps() {
|
||||
const wrapper = shallow(<PipelineList {...props} />);
|
||||
const wrapper = shallowWithIntl(<PipelineList.WrappedComponent {...props} />);
|
||||
await Promise.all([wrapper.instance().componentDidMount]);
|
||||
return wrapper;
|
||||
}
|
||||
|
|
|
@ -6,13 +6,19 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiButton, EuiButtonEmpty, EuiIconTip, EuiInMemoryTable, EuiLink } from '@elastic/eui';
|
||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
||||
import { PIPELINE_LIST } from './constants';
|
||||
|
||||
function getColumns(openPipeline, clonePipeline) {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
name: 'Id',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelinesTable.idColumnLabel"
|
||||
defaultMessage="Id"
|
||||
/>
|
||||
),
|
||||
sortable: true,
|
||||
render: (id, { isCentrallyManaged }) => {
|
||||
const openPipelineClicked = () => openPipeline(id);
|
||||
|
@ -33,20 +39,35 @@ function getColumns(openPipeline, clonePipeline) {
|
|||
},
|
||||
{
|
||||
field: 'description',
|
||||
name: 'Description',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelinesTable.descriptionColumnLabel"
|
||||
defaultMessage="Description"
|
||||
/>
|
||||
),
|
||||
render: description => <span data-test-subj="cellDescription">{description}</span>,
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
},
|
||||
{
|
||||
field: 'lastModifiedHumanized',
|
||||
name: 'Last Modified',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelinesTable.lastModifiedColumnLabel"
|
||||
defaultMessage="Last Modified"
|
||||
/>
|
||||
),
|
||||
render: lastModified => <span data-test-subj="cellLastModified">{lastModified}</span>,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'username',
|
||||
name: 'Modified By',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelinesTable.modifiedByColumnLabel"
|
||||
defaultMessage="Modified By"
|
||||
/>
|
||||
),
|
||||
render: username => <span data-test-subj="cellUsername">{username}</span>,
|
||||
sortable: true,
|
||||
},
|
||||
|
@ -64,7 +85,10 @@ function getColumns(openPipeline, clonePipeline) {
|
|||
onClick={cloneClicked}
|
||||
size="xs"
|
||||
>
|
||||
Clone
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelinesTable.cloneButtonLabel"
|
||||
defaultMessage="Clone"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
) : null;
|
||||
},
|
||||
|
@ -74,7 +98,7 @@ function getColumns(openPipeline, clonePipeline) {
|
|||
];
|
||||
}
|
||||
|
||||
export function PipelinesTable({
|
||||
function PipelinesTableUi({
|
||||
clonePipeline,
|
||||
createPipeline,
|
||||
isReadOnly,
|
||||
|
@ -86,6 +110,7 @@ export function PipelinesTable({
|
|||
pipelines,
|
||||
selection,
|
||||
pageIndex,
|
||||
intl,
|
||||
}) {
|
||||
const pagination = {
|
||||
pageIndex,
|
||||
|
@ -96,7 +121,12 @@ export function PipelinesTable({
|
|||
|
||||
const selectableMessage = (selectable, { id }) =>
|
||||
selectable
|
||||
? `Select pipeline "${id}"`
|
||||
? intl.formatMessage({
|
||||
id: 'xpack.logstash.pipelinesTable.selectablePipelineMessage',
|
||||
defaultMessage: `Select pipeline "{id}"`
|
||||
}, {
|
||||
id,
|
||||
})
|
||||
: PIPELINE_LIST.PIPELINE_NOT_CENTRALLY_MANAGED_TOOLTIP_TEXT;
|
||||
|
||||
const selectionOptions = isSelectable
|
||||
|
@ -116,7 +146,10 @@ export function PipelinesTable({
|
|||
onClick={onDeleteSelectedPipelines}
|
||||
data-test-subj="btnDeletePipeline"
|
||||
>
|
||||
Delete
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelinesTable.deleteButtonLabel"
|
||||
defaultMessage="Delete"
|
||||
/>
|
||||
</EuiButton>
|
||||
) : null;
|
||||
|
||||
|
@ -126,7 +159,12 @@ export function PipelinesTable({
|
|||
{
|
||||
type: 'field_value_selection',
|
||||
field: 'id',
|
||||
name: 'Filter by ID',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelinesTable.filterByIdLabel"
|
||||
defaultMessage="Filter by ID"
|
||||
/>
|
||||
),
|
||||
multiSelect: false,
|
||||
options: pipelines.map(({ id }) => {
|
||||
return {
|
||||
|
@ -146,7 +184,10 @@ export function PipelinesTable({
|
|||
onClick={createPipeline}
|
||||
data-test-subj="btnAdd"
|
||||
>
|
||||
Create pipeline
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.pipelinesTable.createPipelineButtonLabel"
|
||||
defaultMessage="Create pipeline"
|
||||
/>
|
||||
</EuiButton>
|
||||
),
|
||||
};
|
||||
|
@ -168,3 +209,5 @@ export function PipelinesTable({
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const PipelinesTable = injectI18n(PipelinesTableUi);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { PipelinesTable } from './pipelines_table';
|
||||
|
||||
describe('PipelinesTable component', () => {
|
||||
|
@ -38,33 +38,33 @@ describe('PipelinesTable component', () => {
|
|||
});
|
||||
|
||||
it('renders component as expected', () => {
|
||||
const wrapper = shallow(<PipelinesTable {...props} />);
|
||||
const wrapper = shallowWithIntl(<PipelinesTable.WrappedComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calls clone when cloned button clicked', () => {
|
||||
props.pipelines = [{ id: 'testPipeline', isCentrallyManaged: true }];
|
||||
const wrapper = mount(<PipelinesTable {...props} />);
|
||||
const wrapper = mountWithIntl(<PipelinesTable.WrappedComponent {...props} />);
|
||||
wrapper.find('[iconType="copy"]').simulate('click');
|
||||
expect(clonePipeline).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls createPipeline on create button clicked', () => {
|
||||
const wrapper = mount(<PipelinesTable {...props} />);
|
||||
const wrapper = mountWithIntl(<PipelinesTable.WrappedComponent {...props} />);
|
||||
wrapper.find('.euiButton--primary').simulate('click');
|
||||
expect(createPipeline).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls delete prompt on delete click', () => {
|
||||
props.selection = [{ id: 'testPipeline' }];
|
||||
const wrapper = mount(<PipelinesTable {...props} />);
|
||||
const wrapper = mountWithIntl(<PipelinesTable.WrappedComponent {...props} />);
|
||||
wrapper.find('.euiButton--danger').simulate('click');
|
||||
expect(onDeleteSelectedPipelines).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls openPipeline on id click', () => {
|
||||
props.pipelines = [{ id: 'testPipeline', isCentrallyManaged: true }];
|
||||
const wrapper = mount(<PipelinesTable {...props} />);
|
||||
const wrapper = mountWithIntl(<PipelinesTable.WrappedComponent {...props} />);
|
||||
wrapper.find('EuiLink').simulate('click');
|
||||
expect(openPipeline).toHaveBeenCalledWith('testPipeline');
|
||||
});
|
||||
|
|
|
@ -2,6 +2,88 @@
|
|||
|
||||
exports[`UpgradeFailure component passes expected text for new pipeline 1`] = `
|
||||
<UpgradeFailure
|
||||
intl={
|
||||
Object {
|
||||
"defaultFormats": Object {
|
||||
"date": Object {
|
||||
"full": Object {
|
||||
"day": "numeric",
|
||||
"month": "long",
|
||||
"weekday": "long",
|
||||
"year": "numeric",
|
||||
},
|
||||
"long": Object {
|
||||
"day": "numeric",
|
||||
"month": "long",
|
||||
"year": "numeric",
|
||||
},
|
||||
"medium": Object {
|
||||
"day": "numeric",
|
||||
"month": "short",
|
||||
"year": "numeric",
|
||||
},
|
||||
"short": Object {
|
||||
"day": "numeric",
|
||||
"month": "numeric",
|
||||
"year": "2-digit",
|
||||
},
|
||||
},
|
||||
"number": Object {
|
||||
"currency": Object {
|
||||
"style": "currency",
|
||||
},
|
||||
"percent": Object {
|
||||
"style": "percent",
|
||||
},
|
||||
},
|
||||
"time": Object {
|
||||
"full": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
"timeZoneName": "short",
|
||||
},
|
||||
"long": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
"timeZoneName": "short",
|
||||
},
|
||||
"medium": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
},
|
||||
"short": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
},
|
||||
},
|
||||
},
|
||||
"defaultLocale": "en",
|
||||
"formatDate": [Function],
|
||||
"formatHTMLMessage": [Function],
|
||||
"formatMessage": [Function],
|
||||
"formatNumber": [Function],
|
||||
"formatPlural": [Function],
|
||||
"formatRelative": [Function],
|
||||
"formatTime": [Function],
|
||||
"formats": Object {},
|
||||
"formatters": Object {
|
||||
"getDateTimeFormat": [Function],
|
||||
"getMessageFormat": [Function],
|
||||
"getNumberFormat": [Function],
|
||||
"getPluralFormat": [Function],
|
||||
"getRelativeFormat": [Function],
|
||||
},
|
||||
"locale": "en",
|
||||
"messages": Object {},
|
||||
"now": [Function],
|
||||
"onError": [Function],
|
||||
"textComponent": Symbol(react.fragment),
|
||||
"timeZone": null,
|
||||
}
|
||||
}
|
||||
isManualUpgrade={true}
|
||||
isNewPipeline={true}
|
||||
onClose={[MockFunction]}
|
||||
|
@ -282,7 +364,13 @@ exports[`UpgradeFailure component passes expected text for new pipeline 1`] = `
|
|||
<span
|
||||
className="euiButtonEmpty__text"
|
||||
>
|
||||
Go back
|
||||
<FormattedMessage
|
||||
defaultMessage="Go back"
|
||||
id="xpack.logstash.upgradeFailureActions.goBackButtonLabel"
|
||||
values={Object {}}
|
||||
>
|
||||
Go back
|
||||
</FormattedMessage>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
|
@ -304,6 +392,88 @@ exports[`UpgradeFailure component passes expected text for new pipeline 1`] = `
|
|||
|
||||
exports[`UpgradeFailure component passes expected text for not manual upgrade 1`] = `
|
||||
<UpgradeFailure
|
||||
intl={
|
||||
Object {
|
||||
"defaultFormats": Object {
|
||||
"date": Object {
|
||||
"full": Object {
|
||||
"day": "numeric",
|
||||
"month": "long",
|
||||
"weekday": "long",
|
||||
"year": "numeric",
|
||||
},
|
||||
"long": Object {
|
||||
"day": "numeric",
|
||||
"month": "long",
|
||||
"year": "numeric",
|
||||
},
|
||||
"medium": Object {
|
||||
"day": "numeric",
|
||||
"month": "short",
|
||||
"year": "numeric",
|
||||
},
|
||||
"short": Object {
|
||||
"day": "numeric",
|
||||
"month": "numeric",
|
||||
"year": "2-digit",
|
||||
},
|
||||
},
|
||||
"number": Object {
|
||||
"currency": Object {
|
||||
"style": "currency",
|
||||
},
|
||||
"percent": Object {
|
||||
"style": "percent",
|
||||
},
|
||||
},
|
||||
"time": Object {
|
||||
"full": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
"timeZoneName": "short",
|
||||
},
|
||||
"long": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
"timeZoneName": "short",
|
||||
},
|
||||
"medium": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
},
|
||||
"short": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
},
|
||||
},
|
||||
},
|
||||
"defaultLocale": "en",
|
||||
"formatDate": [Function],
|
||||
"formatHTMLMessage": [Function],
|
||||
"formatMessage": [Function],
|
||||
"formatNumber": [Function],
|
||||
"formatPlural": [Function],
|
||||
"formatRelative": [Function],
|
||||
"formatTime": [Function],
|
||||
"formats": Object {},
|
||||
"formatters": Object {
|
||||
"getDateTimeFormat": [Function],
|
||||
"getMessageFormat": [Function],
|
||||
"getNumberFormat": [Function],
|
||||
"getPluralFormat": [Function],
|
||||
"getRelativeFormat": [Function],
|
||||
},
|
||||
"locale": "en",
|
||||
"messages": Object {},
|
||||
"now": [Function],
|
||||
"onError": [Function],
|
||||
"textComponent": Symbol(react.fragment),
|
||||
"timeZone": null,
|
||||
}
|
||||
}
|
||||
isManualUpgrade={false}
|
||||
isNewPipeline={true}
|
||||
onClose={[MockFunction]}
|
||||
|
@ -584,7 +754,13 @@ exports[`UpgradeFailure component passes expected text for not manual upgrade 1`
|
|||
<span
|
||||
className="euiButtonEmpty__text"
|
||||
>
|
||||
Go back
|
||||
<FormattedMessage
|
||||
defaultMessage="Go back"
|
||||
id="xpack.logstash.upgradeFailureActions.goBackButtonLabel"
|
||||
values={Object {}}
|
||||
>
|
||||
Go back
|
||||
</FormattedMessage>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
|
@ -606,6 +782,88 @@ exports[`UpgradeFailure component passes expected text for not manual upgrade 1`
|
|||
|
||||
exports[`UpgradeFailure component passes expected text for not new pipeline 1`] = `
|
||||
<UpgradeFailure
|
||||
intl={
|
||||
Object {
|
||||
"defaultFormats": Object {
|
||||
"date": Object {
|
||||
"full": Object {
|
||||
"day": "numeric",
|
||||
"month": "long",
|
||||
"weekday": "long",
|
||||
"year": "numeric",
|
||||
},
|
||||
"long": Object {
|
||||
"day": "numeric",
|
||||
"month": "long",
|
||||
"year": "numeric",
|
||||
},
|
||||
"medium": Object {
|
||||
"day": "numeric",
|
||||
"month": "short",
|
||||
"year": "numeric",
|
||||
},
|
||||
"short": Object {
|
||||
"day": "numeric",
|
||||
"month": "numeric",
|
||||
"year": "2-digit",
|
||||
},
|
||||
},
|
||||
"number": Object {
|
||||
"currency": Object {
|
||||
"style": "currency",
|
||||
},
|
||||
"percent": Object {
|
||||
"style": "percent",
|
||||
},
|
||||
},
|
||||
"time": Object {
|
||||
"full": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
"timeZoneName": "short",
|
||||
},
|
||||
"long": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
"timeZoneName": "short",
|
||||
},
|
||||
"medium": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
"second": "numeric",
|
||||
},
|
||||
"short": Object {
|
||||
"hour": "numeric",
|
||||
"minute": "numeric",
|
||||
},
|
||||
},
|
||||
},
|
||||
"defaultLocale": "en",
|
||||
"formatDate": [Function],
|
||||
"formatHTMLMessage": [Function],
|
||||
"formatMessage": [Function],
|
||||
"formatNumber": [Function],
|
||||
"formatPlural": [Function],
|
||||
"formatRelative": [Function],
|
||||
"formatTime": [Function],
|
||||
"formats": Object {},
|
||||
"formatters": Object {
|
||||
"getDateTimeFormat": [Function],
|
||||
"getMessageFormat": [Function],
|
||||
"getNumberFormat": [Function],
|
||||
"getPluralFormat": [Function],
|
||||
"getRelativeFormat": [Function],
|
||||
},
|
||||
"locale": "en",
|
||||
"messages": Object {},
|
||||
"now": [Function],
|
||||
"onError": [Function],
|
||||
"textComponent": Symbol(react.fragment),
|
||||
"timeZone": null,
|
||||
}
|
||||
}
|
||||
isManualUpgrade={true}
|
||||
isNewPipeline={false}
|
||||
onClose={[MockFunction]}
|
||||
|
@ -886,7 +1144,13 @@ exports[`UpgradeFailure component passes expected text for not new pipeline 1`]
|
|||
<span
|
||||
className="euiButtonEmpty__text"
|
||||
>
|
||||
Go back
|
||||
<FormattedMessage
|
||||
defaultMessage="Go back"
|
||||
id="xpack.logstash.upgradeFailureActions.goBackButtonLabel"
|
||||
values={Object {}}
|
||||
>
|
||||
Go back
|
||||
</FormattedMessage>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
|
|
|
@ -34,7 +34,11 @@ exports[`UpgradeFailureActions component renders component as expected 1`] = `
|
|||
onClick={[MockFunction]}
|
||||
type="button"
|
||||
>
|
||||
Go back
|
||||
<FormattedMessage
|
||||
defaultMessage="Go back"
|
||||
id="xpack.logstash.upgradeFailureActions.goBackButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -4,17 +4,31 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const UPGRADE_FAILURE = {
|
||||
TITLE: {
|
||||
IS_MANUAL_UPGRADE: 'Upgrade failed',
|
||||
NOT_MANUAL_UPGRADE: 'Time for an upgrade!',
|
||||
IS_MANUAL_UPGRADE: i18n.translate('xpack.logstash.upgradeFailedTitle', {
|
||||
defaultMessage: 'Upgrade failed',
|
||||
}),
|
||||
NOT_MANUAL_UPGRADE: i18n.translate('xpack.logstash.notManualUpgradeTitle', {
|
||||
defaultMessage: 'Time for an upgrade!',
|
||||
}),
|
||||
},
|
||||
MESSAGE: {
|
||||
IS_NEW_PIPELINE: 'Before you can add a pipeline, we need to upgrade your configuration.',
|
||||
NOT_NEW_PIPELINE: 'Before you can edit this pipeline, we need to upgrade your configuration.',
|
||||
IS_NEW_PIPELINE: i18n.translate('xpack.logstash.newPipelineMessage', {
|
||||
defaultMessage: 'Before you can add a pipeline, we need to upgrade your configuration.',
|
||||
}),
|
||||
NOT_NEW_PIPELINE: i18n.translate('xpack.logstash.notNewPipelineMessage', {
|
||||
defaultMessage: 'Before you can edit this pipeline, we need to upgrade your configuration.',
|
||||
}),
|
||||
},
|
||||
UPGRADE_BUTTON_TEXT: {
|
||||
IS_MANUAL_UPGRADE: 'Try again',
|
||||
NOT_MANUAL_UPGRADE: 'Upgrade',
|
||||
IS_MANUAL_UPGRADE: i18n.translate('xpack.logstash.manualUpgradeButtonLabel', {
|
||||
defaultMessage: 'Try again',
|
||||
}),
|
||||
NOT_MANUAL_UPGRADE: i18n.translate('xpack.logstash.notManualUpgradeButtonLabel', {
|
||||
defaultMessage: 'Upgrade',
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { UpgradeFailure } from './upgrade_failure';
|
||||
|
||||
describe('UpgradeFailure component', () => {
|
||||
|
@ -26,29 +26,29 @@ describe('UpgradeFailure component', () => {
|
|||
});
|
||||
|
||||
it('renders component as expected', () => {
|
||||
const wrapper = shallow(<UpgradeFailure {...props} />);
|
||||
const wrapper = shallowWithIntl(<UpgradeFailure {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('passes expected text for new pipeline', () => {
|
||||
const wrapper = mount(<UpgradeFailure {...props} />);
|
||||
const wrapper = mountWithIntl(<UpgradeFailure {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('passes expected text for not new pipeline', () => {
|
||||
props.isNewPipeline = false;
|
||||
const wrapper = mount(<UpgradeFailure {...props} />);
|
||||
const wrapper = mountWithIntl(<UpgradeFailure {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('passes expected text for not manual upgrade', () => {
|
||||
props.isManualUpgrade = false;
|
||||
const wrapper = mount(<UpgradeFailure {...props} />);
|
||||
const wrapper = mountWithIntl(<UpgradeFailure {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('propogates onClose and onRetry functions to child', () => {
|
||||
const wrapper = mount(<UpgradeFailure {...props} />);
|
||||
const wrapper = mountWithIntl(<UpgradeFailure {...props} />);
|
||||
expect(wrapper.find('UpgradeFailureActions').props().onClose).toEqual(onClose);
|
||||
expect(wrapper.find('UpgradeFailureActions').props().onRetry).toEqual(onRetry);
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export function UpgradeFailureActions({ onClose, onRetry, upgradeButtonText }) {
|
||||
return (
|
||||
|
@ -18,7 +19,10 @@ export function UpgradeFailureActions({ onClose, onRetry, upgradeButtonText }) {
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty color="primary" onClick={onClose}>
|
||||
Go back
|
||||
<FormattedMessage
|
||||
id="xpack.logstash.upgradeFailureActions.goBackButtonLabel"
|
||||
defaultMessage="Go back"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { UpgradeFailureActions } from './upgrade_failure_actions';
|
||||
|
||||
describe('UpgradeFailureActions component', () => {
|
||||
|
@ -24,18 +24,18 @@ describe('UpgradeFailureActions component', () => {
|
|||
});
|
||||
|
||||
it('renders component as expected', () => {
|
||||
const wrapper = shallow(<UpgradeFailureActions {...props} />);
|
||||
const wrapper = shallowWithIntl(<UpgradeFailureActions {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calls onRetry on update click', () => {
|
||||
const wrapper = mount(<UpgradeFailureActions {...props} />);
|
||||
const wrapper = mountWithIntl(<UpgradeFailureActions {...props} />);
|
||||
wrapper.find('EuiButton').simulate('click');
|
||||
expect(onRetry).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('calls onClose on "Go back" click', () => {
|
||||
const wrapper = mount(<UpgradeFailureActions {...props} />);
|
||||
const wrapper = mountWithIntl(<UpgradeFailureActions {...props} />);
|
||||
wrapper.find('EuiButtonEmpty').simulate('click');
|
||||
expect(onClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/registry/feature_catalogue';
|
||||
|
||||
FeatureCatalogueRegistryProvider.register(($injector) => {
|
||||
FeatureCatalogueRegistryProvider.register(($injector, i18n) => {
|
||||
|
||||
const licenseService = $injector.get('logstashLicenseService');
|
||||
if (!licenseService.enableLinks) {
|
||||
|
@ -15,8 +15,12 @@ FeatureCatalogueRegistryProvider.register(($injector) => {
|
|||
|
||||
return {
|
||||
id: 'management_logstash',
|
||||
title: 'Logstash Pipelines',
|
||||
description: 'Create, delete, update, and clone data ingestion pipelines.',
|
||||
title: i18n('xpack.logstash.homeFeature.logstashPipelinesTitle', {
|
||||
defaultMessage: 'Logstash Pipelines',
|
||||
}),
|
||||
description: i18n('xpack.logstash.homeFeature.logstashPipelinesDescription', {
|
||||
defaultMessage: 'Create, delete, update, and clone data ingestion pipelines.',
|
||||
}),
|
||||
icon: 'pipelineApp',
|
||||
path: '/app/kibana#/management/logstash/pipelines',
|
||||
showOnHomePage: true,
|
||||
|
|
|
@ -8,6 +8,7 @@ import React from 'react';
|
|||
import { render } from 'react-dom';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import { UpgradeFailure } from '../../../../components/upgrade_failure';
|
||||
|
||||
const app = uiModules.get('xpack/logstash');
|
||||
|
@ -29,12 +30,14 @@ app.directive('upgradeFailure', $injector => {
|
|||
const isManualUpgrade = !!$route.current.params.retry;
|
||||
|
||||
render(
|
||||
<UpgradeFailure
|
||||
isNewPipeline={isNewPipeline}
|
||||
isManualUpgrade={isManualUpgrade}
|
||||
onRetry={onRetry}
|
||||
onClose={onClose}
|
||||
/>,
|
||||
<I18nProvider>
|
||||
<UpgradeFailure
|
||||
isNewPipeline={isNewPipeline}
|
||||
isManualUpgrade={isManualUpgrade}
|
||||
onRetry={onRetry}
|
||||
onClose={onClose}
|
||||
/>
|
||||
</I18nProvider>,
|
||||
el[0]
|
||||
);
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import routes from 'ui/routes';
|
||||
import { toastNotifications } from 'ui/notify';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import template from './pipeline_edit_route.html';
|
||||
import 'plugins/logstash/services/pipeline';
|
||||
import 'plugins/logstash/services/license';
|
||||
|
@ -50,7 +51,12 @@ routes
|
|||
return licenseService.checkValidity()
|
||||
.then(() => {
|
||||
if (err.status !== 403) {
|
||||
toastNotifications.addDanger(`Couldn't load pipeline. Error: '${err.statusText}'.`);
|
||||
toastNotifications.addDanger(i18n.translate('xpack.logstash.couldNotLoadPipelineErrorNotification', {
|
||||
defaultMessage: `Couldn't load pipeline. Error: '{errStatusText}'.`,
|
||||
values: {
|
||||
errStatusText: err.statusText,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
kbnUrl.redirect('/management/logstash/pipelines');
|
||||
|
|
|
@ -5,9 +5,12 @@
|
|||
*/
|
||||
|
||||
import { management } from 'ui/management';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
management.getSection('logstash').register('pipelines', {
|
||||
display: 'Pipelines',
|
||||
display: i18n.translate('xpack.logstash.managementSection.pipelinesTitle', {
|
||||
defaultMessage: 'Pipelines',
|
||||
}),
|
||||
order: 10,
|
||||
url: '#/management/logstash/pipelines/'
|
||||
});
|
||||
|
@ -17,13 +20,17 @@ management.getSection('logstash/pipelines').register('pipeline', {
|
|||
});
|
||||
|
||||
management.getSection('logstash/pipelines/pipeline').register('edit', {
|
||||
display: 'Edit pipeline',
|
||||
display: i18n.translate('xpack.logstash.managementSection.editPipelineTitle', {
|
||||
defaultMessage: 'Edit pipeline',
|
||||
}),
|
||||
order: 1,
|
||||
visible: false
|
||||
});
|
||||
|
||||
management.getSection('logstash/pipelines/pipeline').register('new', {
|
||||
display: 'Create pipeline',
|
||||
display: i18n.translate('xpack.logstash.managementSection.createPipelineTitle', {
|
||||
defaultMessage: 'Create pipeline',
|
||||
}),
|
||||
order: 1,
|
||||
visible: false
|
||||
});
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export function checkLicense(xpackLicenseInfo) {
|
||||
// If, for some reason, we cannot get the license information
|
||||
// from Elasticsearch, assume worst case and disable the Logstash pipeline UI
|
||||
|
@ -12,7 +14,9 @@ export function checkLicense(xpackLicenseInfo) {
|
|||
isAvailable: false,
|
||||
enableLinks: false,
|
||||
isReadOnly: false,
|
||||
message: 'You cannot manage Logstash pipelines because license information is not available at this time.'
|
||||
message: i18n.translate('xpack.logstash.managementSection.notPossibleToManagePipelinesMessage', {
|
||||
defaultMessage: 'You cannot manage Logstash pipelines because license information is not available at this time.',
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,8 +34,10 @@ export function checkLicense(xpackLicenseInfo) {
|
|||
|
||||
// Security is not enabled in ES
|
||||
if (!isSecurityEnabled) {
|
||||
const message = 'Security must be enabled in order to use Logstash pipeline management features.'
|
||||
+ ' Please set xpack.security.enabled: true in your elasticsearch.yml.';
|
||||
const message = i18n.translate('xpack.logstash.managementSection.enableSecurityDescription', {
|
||||
defaultMessage: 'Security must be enabled in order to use Logstash pipeline management features.' +
|
||||
' Please set xpack.security.enabled: true in your elasticsearch.yml.',
|
||||
});
|
||||
return {
|
||||
isAvailable: false,
|
||||
enableLinks: false,
|
||||
|
@ -46,7 +52,10 @@ export function checkLicense(xpackLicenseInfo) {
|
|||
isAvailable: false,
|
||||
enableLinks: false,
|
||||
isReadOnly: false,
|
||||
message: `Your ${licenseType} license does not support Logstash pipeline management features. Please upgrade your license.`
|
||||
message: i18n.translate('xpack.logstash.managementSection.licenseDoesNotSupportDescription', {
|
||||
defaultMessage: 'Your {licenseType} license does not support Logstash pipeline management features. Please upgrade your license.',
|
||||
values: { licenseType },
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -56,7 +65,10 @@ export function checkLicense(xpackLicenseInfo) {
|
|||
isAvailable: true,
|
||||
enableLinks: true,
|
||||
isReadOnly: true,
|
||||
message: `You cannot edit, create, or delete your Logstash pipelines because your ${licenseType} license has expired.`
|
||||
message: i18n.translate('xpack.logstash.managementSection.pipelineCrudOperationsNotAllowedDescription', {
|
||||
defaultMessage: 'You cannot edit, create, or delete your Logstash pipelines because your {licenseType} license has expired.',
|
||||
values: { licenseType },
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import Boom from 'boom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
/**
|
||||
* Wraps ES errors into a Boom error response and returns it
|
||||
|
@ -16,7 +17,9 @@ import Boom from 'boom';
|
|||
export function wrapEsError(err) {
|
||||
const statusCode = err.statusCode;
|
||||
if (statusCode === 403) {
|
||||
return Boom.forbidden('Insufficient user permissions for managing Logstash pipelines');
|
||||
return Boom.forbidden(i18n.translate('xpack.logstash.insufficientUserPermissionsDescription', {
|
||||
defaultMessage: 'Insufficient user permissions for managing Logstash pipelines',
|
||||
}));
|
||||
}
|
||||
return Boom.boomify(err, { statusCode: err.statusCode });
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import moment from 'moment';
|
||||
import { badRequest } from 'boom';
|
||||
import { get } from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
/**
|
||||
* This model deals with a pipeline object from ES and converts it to Kibana downstream
|
||||
|
@ -70,7 +71,9 @@ export class Pipeline {
|
|||
// generate Pipeline object from elasticsearch response
|
||||
static fromUpstreamJSON(upstreamPipeline) {
|
||||
if (!upstreamPipeline._id) {
|
||||
throw badRequest('upstreamPipeline argument must contain an id property');
|
||||
throw badRequest(i18n.translate('xpack.logstash.upstreamPipelineArgumentMustContainAnIdPropertyErrorMessage', {
|
||||
defaultMessage: 'upstreamPipeline argument must contain an id property',
|
||||
}));
|
||||
}
|
||||
const id = get(upstreamPipeline, '_id');
|
||||
const description = get(upstreamPipeline, '_source.description');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue