"Index management" translations (#21687)

Apply translations for Index management on Management tab
This commit is contained in:
Aliaksandr Yankouski 2018-08-17 11:25:47 +03:00 committed by pavel06081991
parent cb8c1de733
commit 42c291a752
27 changed files with 544 additions and 169 deletions

View file

@ -29,7 +29,7 @@ import { intl } from './mocks/intl';
* @param options properties to pass into shallow wrapper
* @return The wrapper instance around the rendered output with intl object in context
*/
export function shallowWithIntl(node, { context, childContextTypes, ...props } = {}) {
export function shallowWithIntl(node, { context = {}, childContextTypes = {}, ...props } = {}) {
if (!node) {
throw new Error(`First argument should be cheerio object or React element, not ${node}`);
}

View file

@ -27,4 +27,5 @@ export const intl = {
formatPlural: jest.fn().mockImplementation(value => value),
formatHTMLMessage: jest.fn().mockImplementation(({ defaultMessage }) => defaultMessage),
now: jest.fn().mockImplementation(() => new Date(1531834573179)),
textComponent: 'span'
};

View file

@ -84,6 +84,7 @@
"@elastic/node-phantom-simple": "2.2.4",
"@elastic/numeral": "2.3.2",
"@kbn/datemath": "link:../packages/kbn-datemath",
"@kbn/i18n": "link:../packages/kbn-i18n",
"@kbn/ui-framework": "link:../packages/kbn-ui-framework",
"@samverschueren/stream-to-observable": "^0.3.0",
"@slack/client": "^4.2.2",

View file

@ -90,51 +90,51 @@ Array [
exports[`index table should show the right context menu options when more than one closed index is selected 1`] = `
Array [
"Open indices",
"Delete indices",
"Open {entity}",
"Delete {entity}",
]
`;
exports[`index table should show the right context menu options when more than one open index is selected 1`] = `
Array [
"Close indices",
"Force merge indices",
"Refresh indices",
"Clear indices cache",
"Flush indices",
"Delete indices",
"Close {entity}",
"Force merge {entity}",
"Refresh {entity}",
"Clear {entity} cache",
"Flush {entity}",
"Delete {entity}",
]
`;
exports[`index table should show the right context menu options when one index is selected and closed 1`] = `
Array [
"Show index settings",
"Show index mapping",
"Edit index settings",
"Open index",
"Delete index",
"Show {entity} settings",
"Show {entity} mapping",
"Edit {entity} settings",
"Open {entity}",
"Delete {entity}",
]
`;
exports[`index table should show the right context menu options when one index is selected and open 1`] = `
Array [
"Show index settings",
"Show index mapping",
"Show index stats",
"Edit index settings",
"Close index",
"Force merge index",
"Refresh index",
"Clear index cache",
"Flush index",
"Delete index",
"Show {entity} settings",
"Show {entity} mapping",
"Show {entity} stats",
"Edit {entity} settings",
"Close {entity}",
"Force merge {entity}",
"Refresh {entity}",
"Clear {entity} cache",
"Flush {entity}",
"Delete {entity}",
]
`;
exports[`index table should show the right context menu options when one open and one closed index is selected 1`] = `
Array [
"Open indices",
"Delete indices",
"Open {entity}",
"Delete {entity}",
]
`;

View file

@ -11,7 +11,7 @@ import { Provider } from 'react-redux';
import { loadIndicesSuccess } from '../../public/store/actions';
import { indexManagementStore } from '../../public/store';
import { BASE_PATH } from '../../common/constants';
import { mount } from 'enzyme';
import { mountWithIntl } from '../../../../test_utils/enzyme_helpers';
// axios has a $http like interface so using it to simulate $http
import axios from 'axios';
import { setHttpClient } from '../../public/services/api';
@ -88,13 +88,13 @@ const openMenuAndClickButton = (rendered, rowIndex, buttonIndex) => {
contextMenuButtons.at(buttonIndex).simulate('click');
};
const testEditor = (buttonIndex, rowIndex = 0) => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
openMenuAndClickButton(rendered, rowIndex, buttonIndex);
rendered.update();
snapshot(findTestSubject(rendered, 'detailPanelTabSelected').text());
};
const testAction = (buttonIndex, done, rowIndex = 0) => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
let count = 0;
store.subscribe(() => {
if (count > 1) {
@ -148,7 +148,7 @@ describe('index table', () => {
});
test('should change pages when a pagination link is clicked on', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
snapshot(namesText(rendered));
const pagingButtons = rendered.find('.euiPaginationButton');
pagingButtons.at(2).simulate('click');
@ -156,7 +156,7 @@ describe('index table', () => {
snapshot(namesText(rendered));
});
test('should show more when per page value is increased', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const perPageButton = rendered.find('span[children="Rows per page: 10"]');
perPageButton.simulate('click');
rendered.update();
@ -166,7 +166,7 @@ describe('index table', () => {
expect(namesText(rendered).length).toBe(50);
});
test('should show the Actions menu button only when at least one row is selected', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
let button = findTestSubject(rendered, 'indexTableContextMenuButton');
expect(button.length).toEqual(0);
const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox');
@ -176,7 +176,7 @@ describe('index table', () => {
expect(button.length).toEqual(1);
});
test('should show system indices only when the switch is turned on', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
snapshot(
rendered
.find(
@ -195,14 +195,14 @@ describe('index table', () => {
);
});
test('should filter based on content of search input', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const searchInput = findTestSubject(rendered, 'indexTableFilterInput');
searchInput.simulate('change', { target: { value: 'testy0' } });
rendered.update();
snapshot(namesText(rendered));
});
test('should sort when header is clicked', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const nameHeader = findTestSubject(
rendered,
'indexTableHeaderCell-name'
@ -215,7 +215,7 @@ describe('index table', () => {
snapshot(namesText(rendered));
});
test('should open the index detail slideout when the index name is clicked', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
expect(findTestSubject(rendered, 'indexDetailFlyout').length).toBe(0);
const indexNameLink = names(rendered).at(0);
indexNameLink.simulate('click');
@ -223,7 +223,7 @@ describe('index table', () => {
expect(findTestSubject(rendered, 'indexDetailFlyout').length).toBe(1);
});
test('should show the right context menu options when one index is selected and open', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox');
checkboxes.at(0).simulate('change', { target: { checked: true } });
rendered.update();
@ -240,7 +240,7 @@ describe('index table', () => {
);
});
test('should show the right context menu options when one index is selected and closed', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox');
checkboxes.at(1).simulate('change', { target: { checked: true } });
rendered.update();
@ -257,7 +257,7 @@ describe('index table', () => {
);
});
test('should show the right context menu options when one open and one closed index is selected', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox');
checkboxes.at(0).simulate('change', { target: { checked: true } });
checkboxes.at(1).simulate('change', { target: { checked: true } });
@ -275,7 +275,7 @@ describe('index table', () => {
);
});
test('should show the right context menu options when more than one open index is selected', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox');
checkboxes.at(0).simulate('change', { target: { checked: true } });
checkboxes.at(2).simulate('change', { target: { checked: true } });
@ -293,7 +293,7 @@ describe('index table', () => {
);
});
test('should show the right context menu options when more than one closed index is selected', () => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox');
checkboxes.at(1).simulate('change', { target: { checked: true } });
checkboxes.at(3).simulate('change', { target: { checked: true } });
@ -320,7 +320,7 @@ describe('index table', () => {
testAction(6, done);
});
test('force merge button works from context menu', done => {
const rendered = mount(component);
const rendered = mountWithIntl(component);
const rowIndex = 0;
openMenuAndClickButton(rendered, rowIndex, 5);
snapshot(status(rendered, rowIndex));

View file

@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
import {
INDEX_CLEARING_CACHE,
INDEX_CLOSED,
@ -16,12 +17,28 @@ import {
} from '../../common/constants';
export const indexStatusLabels = {
[INDEX_CLEARING_CACHE]: 'clearing cache...',
[INDEX_CLOSED]: 'closed',
[INDEX_CLOSING]: 'closing...',
[INDEX_MERGING]: 'merging...',
[INDEX_OPENING]: 'opening...',
[INDEX_REFRESHING]: 'refreshing...',
[INDEX_FLUSHING]: 'flushing...',
[INDEX_FORCEMERGING]: 'forcing merge...'
[INDEX_CLEARING_CACHE]: i18n.translate('xpack.idxMgmt.indexStatusLabels.clearingCacheStatusLabel', {
defaultMessage: 'clearing cache...',
}),
[INDEX_CLOSED]: i18n.translate('xpack.idxMgmt.indexStatusLabels.closedStatusLabel', {
defaultMessage: 'closed',
}),
[INDEX_CLOSING]: i18n.translate('xpack.idxMgmt.indexStatusLabels.closingStatusLabel', {
defaultMessage: 'closing...',
}),
[INDEX_MERGING]: i18n.translate('xpack.idxMgmt.indexStatusLabels.mergingStatusLabel', {
defaultMessage: 'merging...',
}),
[INDEX_OPENING]: i18n.translate('xpack.idxMgmt.indexStatusLabels.openingStatusLabel', {
defaultMessage: 'opening...',
}),
[INDEX_REFRESHING]: i18n.translate('xpack.idxMgmt.indexStatusLabels.refreshingStatusLabel', {
defaultMessage: 'refreshing...',
}),
[INDEX_FLUSHING]: i18n.translate('xpack.idxMgmt.indexStatusLabels.flushingStatusLabel', {
defaultMessage: 'flushing...',
}),
[INDEX_FORCEMERGING]: i18n.translate('xpack.idxMgmt.indexStatusLabels.forcingMergeStatusLabel', {
defaultMessage: 'forcing merge...',
})
};

View file

@ -5,12 +5,13 @@
*/
import { management } from 'ui/management';
import { i18n } from '@kbn/i18n';
import { BASE_PATH } from '../common/constants';
const esSection = management.getSection('elasticsearch');
esSection.register('index_management', {
visible: true,
display: 'Index Management',
display: i18n.translate('xpack.idxMgmt.appTitle', { defaultMessage: 'Index Management' }),
order: 1,
url: `#${BASE_PATH}home`
});

View file

@ -8,6 +8,7 @@ import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { HashRouter } from 'react-router-dom';
import { I18nProvider } from '@kbn/i18n/react';
import { setHttpClient } from './services/api';
import { App } from './app';
@ -21,11 +22,13 @@ import { indexManagementStore } from './store';
const renderReact = async (elem) => {
render(
<Provider store={indexManagementStore()}>
<HashRouter>
<App />
</HashRouter>
</Provider>,
<I18nProvider>
<Provider store={indexManagementStore()}>
<HashRouter>
<App />
</HashRouter>
</Provider>
</I18nProvider>,
elem
);
};

View file

@ -5,7 +5,8 @@
*/
import React, { Component } from 'react';
import { Route } from "react-router-dom";
import { injectI18n } from '@kbn/i18n/react';
import { Route } from 'react-router-dom';
import { ShowJson } from './show_json';
import { Summary } from './summary';
import { EditSettingsJson } from './edit_settings_json';
@ -21,15 +22,15 @@ import {
EuiTab,
EuiTitle
} from '@elastic/eui';
import { IndexActionsContextMenu } from "../../components";
import { INDEX_OPEN } from "../../../../../common/constants";
import { IndexActionsContextMenu } from '../../components';
import { INDEX_OPEN } from '../../../../../common/constants';
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
const tabs = ['Summary', 'Settings', 'Mapping', 'Stats', 'Edit settings'];
export class DetailPanel extends Component {
export class DetailPanelUi extends Component {
renderTabs() {
const { panelType, indexName, indexStatus, openDetailPanel } = this.props;
@ -50,7 +51,7 @@ export class DetailPanel extends Component {
}
render() {
const { panelType, indexName, closeDetailPanel } = this.props;
const { panelType, indexName, closeDetailPanel, intl } = this.props;
if (!panelType) {
return null;
}
@ -94,7 +95,10 @@ export class DetailPanel extends Component {
anchorPosition="upRight"
detailPanel={true}
iconType="arrowUp"
label="Manage"
label={intl.formatMessage({
id: 'xpack.idxMgmt.detailPanel.manageContextMenuLabel',
defaultMessage: 'Manage',
})}
/>
)}
/>
@ -105,3 +109,5 @@ export class DetailPanel extends Component {
);
}
}
export const DetailPanel = injectI18n(DetailPanelUi);

View file

@ -5,6 +5,7 @@
*/
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { settingsDocumentationLink } from '../../../../../lib/documentation_links';
import {
@ -118,7 +119,10 @@ export class EditSettingsJson extends React.PureComponent {
<EuiFlexItem>
<EuiTitle>
<p>
Edit, then save your JSON
<FormattedMessage
id="xpack.idxMgmt.editSettingsJSON.saveJSONDescription"
defaultMessage="Edit, then save your JSON"
/>
</p>
</EuiTitle>
</EuiFlexItem>
@ -130,7 +134,10 @@ export class EditSettingsJson extends React.PureComponent {
onClick={this.commitSettings}
disabled={!this.state.valid}
>
Save
<FormattedMessage
id="xpack.idxMgmt.editSettingsJSON.saveJSONButtonLabel"
defaultMessage="Save"
/>
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
@ -140,7 +147,10 @@ export class EditSettingsJson extends React.PureComponent {
target="_blank"
rel="noopener noreferrer"
>
Settings reference
<FormattedMessage
id="xpack.idxMgmt.editSettingsJSON.settingsReferenceLinkText"
defaultMessage="Settings reference"
/>
</EuiLink>
<EuiSpacer />
<div

View file

@ -4,24 +4,41 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React from "react";
import React from 'react';
import { i18n } from '@kbn/i18n';
import { healthToColor } from '../../../../../services';
import {
EuiHealth,
EuiDescriptionList,
EuiDescriptionListTitle,
EuiDescriptionListDescription,
} from "@elastic/eui";
} from '@elastic/eui';
const HEADERS = {
health: "Health",
status: "Status",
primary: "Primaries",
replica: "Replicas",
documents: "Docs Count",
documents_deleted: "Docs Deleted",
size: "Storage Size",
primary_size: "Primary Storage Size"
health: i18n.translate('xpack.idxMgmt.summary.headers.healthHeader', {
defaultMessage: 'Health',
}),
status: i18n.translate('xpack.idxMgmt.summary.headers.statusHeader', {
defaultMessage: 'Status',
}),
primary: i18n.translate('xpack.idxMgmt.summary.headers.primaryHeader', {
defaultMessage: 'Primaries',
}),
replica: i18n.translate('xpack.idxMgmt.summary.headers.replicaHeader', {
defaultMessage: 'Replicas',
}),
documents: i18n.translate('xpack.idxMgmt.summary.headers.documentsHeader', {
defaultMessage: 'Docs Count',
}),
documents_deleted: i18n.translate('xpack.idxMgmt.summary.headers.deletedDocumentsHeader', {
defaultMessage: 'Docs Deleted',
}),
size: i18n.translate('xpack.idxMgmt.summary.headers.storageSizeHeader', {
defaultMessage: 'Storage Size',
}),
primary_size: i18n.translate('xpack.idxMgmt.summary.headers.primaryStorageSizeHeader', {
defaultMessage: 'Primary Storage Size',
})
};
export class Summary extends React.PureComponent {

View file

@ -5,8 +5,8 @@
*/
import React, { Component } from 'react';
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
import { all } from 'lodash';
import pluralize from 'pluralize';
import {
EuiButton,
EuiCallOut,
@ -23,7 +23,7 @@ import {
import { flattenPanelTree } from '../../../../lib/flatten_panel_tree';
import { INDEX_OPEN } from '../../../../../common/constants';
export class IndexActionsContextMenu extends Component {
class IndexActionsContextMenuUi extends Component {
constructor(props) {
super(props);
@ -45,7 +45,8 @@ export class IndexActionsContextMenu extends Component {
showSettings,
detailPanel,
indexNames,
indexStatusByName
indexStatusByName,
intl
} = this.props;
const allOpen = all(indexNames, indexName => {
return indexStatusByName[indexName] === INDEX_OPEN;
@ -56,14 +57,20 @@ export class IndexActionsContextMenu extends Component {
const items = [];
if (!detailPanel && oneIndexSelected) {
items.push({
name: `Show ${entity} settings`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.showEntitySettingsLabel',
defaultMessage: 'Show {entity} settings',
}, { entity }),
icon: <EuiIcon type="indexSettings" />,
onClick: () => {
this.closePopoverAndExecute(showSettings);
}
});
items.push({
name: `Show ${entity} mapping`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.showEntityMappingLabel',
defaultMessage: 'Show {entity} mapping',
}, { entity }),
icon: <EuiIcon type="indexMapping" />,
onClick: () => {
this.closePopoverAndExecute(showMapping);
@ -71,7 +78,10 @@ export class IndexActionsContextMenu extends Component {
});
if (allOpen) {
items.push({
name: `Show ${entity} stats`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.showEntityStatsLabel',
defaultMessage: 'Show {entity} stats',
}, { entity }),
icon: <EuiIcon type="stats" />,
onClick: () => {
this.closePopoverAndExecute(showStats);
@ -79,7 +89,10 @@ export class IndexActionsContextMenu extends Component {
});
}
items.push({
name: `Edit ${entity} settings`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.editEntitySettingsLabel',
defaultMessage: 'Edit {entity} settings',
}, { entity }),
icon: <EuiIcon type="indexEdit" />,
onClick: () => {
this.closePopoverAndExecute(editIndex);
@ -88,14 +101,20 @@ export class IndexActionsContextMenu extends Component {
}
if (allOpen) {
items.push({
name: `Close ${entity}`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.closeEntityLabel',
defaultMessage: 'Close {entity}',
}, { entity }),
icon: <EuiIcon type="indexClose" />,
onClick: () => {
this.closePopoverAndExecute(closeIndices);
}
});
items.push({
name: `Force merge ${entity}`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.forceMergeEntityLabel',
defaultMessage: 'Force merge {entity}',
}, { entity }),
icon: <EuiIcon type="merge" />,
onClick: () => {
this.closePopover();
@ -103,21 +122,30 @@ export class IndexActionsContextMenu extends Component {
}
});
items.push({
name: `Refresh ${entity}`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.refreshEntityLabel',
defaultMessage: 'Refresh {entity}',
}, { entity }),
icon: <EuiIcon type="refresh" />,
onClick: () => {
this.closePopoverAndExecute(refreshIndices);
}
});
items.push({
name: `Clear ${entity} cache`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.clearEntityCacheLabel',
defaultMessage: 'Clear {entity} cache',
}, { entity }),
icon: <EuiIcon type="broom" />,
onClick: () => {
this.closePopoverAndExecute(clearCacheIndices);
}
});
items.push({
name: `Flush ${entity}`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.flushEntityLabel',
defaultMessage: 'Flush {entity}',
}, { entity }),
icon: <EuiIcon type="indexFlush" />,
onClick: () => {
this.closePopoverAndExecute(flushIndices);
@ -125,7 +153,10 @@ export class IndexActionsContextMenu extends Component {
});
} else {
items.push({
name: `Open ${entity}`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.openEntityLabel',
defaultMessage: 'Open {entity}',
}, { entity }),
icon: <EuiIcon type="indexOpen" />,
onClick: () => {
this.closePopoverAndExecute(openIndices);
@ -133,7 +164,10 @@ export class IndexActionsContextMenu extends Component {
});
}
items.push({
name: `Delete ${entity}`,
name: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.deleteEntityLabel',
defaultMessage: 'Delete {entity}',
}, { entity }),
icon: <EuiIcon type="trash" />,
onClick: () => {
this.closePopover();
@ -145,7 +179,10 @@ export class IndexActionsContextMenu extends Component {
});
const panelTree = {
id: 0,
title: `${entityUpper} options`,
title: intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.panelTitle',
defaultMessage: '{entityUpper} options',
}, { entityUpper }),
items
};
return flattenPanelTree(panelTree);
@ -190,18 +227,24 @@ export class IndexActionsContextMenu extends Component {
forcemergeSegmentsError = () => {
const { forcemergeSegments } = this.state;
const { intl } = this.props;
if (!forcemergeSegments || forcemergeSegments.match(/^([1-9][0-9]*)?$/)) {
return;
} else {
return 'The number of segments must be greater than zero.';
return intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.segmentsNumberErrorMessage',
defaultMessage: 'The number of segments must be greater than zero.',
});
}
};
forcemergeSegmentsModal = () => {
const helpText = `Merge the segments in an index until the number
is reduced to this or fewer segments. The default is 1.`;
const { forcemergeIndices, indexNames, intl } = this.props;
const helpText = intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.forceMerge.forceMergeSegmentsHelpText',
defaultMessage: 'Merge the segments in an index until the number is reduced to this or fewer segments. The default is 1.',
});
const oneIndexSelected = this.oneIndexSelected();
const entity = this.getEntity(oneIndexSelected);
const { forcemergeIndices, indexNames } = this.props;
const { showForcemergeSegmentsModal } = this.state;
if (!showForcemergeSegmentsModal) {
return null;
@ -209,7 +252,10 @@ export class IndexActionsContextMenu extends Component {
return (
<EuiOverlayMask>
<EuiConfirmModal
title={`Force merge`}
title={intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.forceMerge.confirmModal.modalTitle',
defaultMessage: 'Force merge',
})}
onCancel={this.closeForcemergeSegmentsModal}
onConfirm={() => {
if (!this.forcemergeSegmentsError()) {
@ -222,12 +268,27 @@ export class IndexActionsContextMenu extends Component {
});
}
}}
cancelButtonText="Cancel"
confirmButtonText="Force merge"
cancelButtonText={
intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.forceMerge.confirmModal.cancelButtonText',
defaultMessage: 'Cancel',
})
}
confirmButtonText={
intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.forceMerge.confirmModal.confirmButtonText',
defaultMessage: 'Force merge',
})
}
>
<div>
<p>
You are about to force merge {oneIndexSelected ? 'this' : 'these'}{' '}
<FormattedMessage
id="xpack.idxMgmt.indexActionsMenu.forceMerge.forceMergeDescription"
defaultMessage="You are about to force merge {mergedKeyword}"
values={{ mergedKeyword: oneIndexSelected ? 'this' : 'these' }}
/>
{' '}
{entity}:
</p>
<ul>
@ -236,14 +297,22 @@ export class IndexActionsContextMenu extends Component {
))}
</ul>
<EuiCallOut
title="Proceed with caution!"
title={intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.forceMerge.proceedWithCautionCallOutTitle',
defaultMessage: 'Proceed with caution!',
})}
color="warning"
iconType="help"
>
<p>
Force merging a large index or an index that is not read-only can
potentially cause performance and stability issues in the cluster
if it is not run properly (run against non-read-only indices) or run during peak hours.
<FormattedMessage
id="xpack.idxMgmt.indexActionsMenu.forceMerge.forceMergeWarningDescription"
defaultMessage="
Force merging a large index or an index that is not read-only can
potentially cause performance and stability issues in the cluster
if it is not run properly (run against non-read-only indices) or run during peak hours.
"
/>
</p>
</EuiCallOut>
<EuiSpacer size="m" />
@ -252,7 +321,10 @@ export class IndexActionsContextMenu extends Component {
error={this.forcemergeSegmentsError()}
>
<EuiFormRow
label="Maximum number of segments per shard"
label={intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.forceMerge.maximumNumberOfSegmentsFormRowLabel',
defaultMessage: 'Maximum number of segments per shard',
})}
helpText={helpText}
>
<EuiFieldText
@ -272,7 +344,7 @@ export class IndexActionsContextMenu extends Component {
confirmDeleteModal = () => {
const oneIndexSelected = this.oneIndexSelected();
const entity = this.getEntity(oneIndexSelected);
const { deleteIndices, indexNames } = this.props;
const { deleteIndices, indexNames, intl } = this.props;
const { showDeleteConfirmation } = this.state;
if (!showDeleteConfirmation) {
return null;
@ -280,15 +352,35 @@ export class IndexActionsContextMenu extends Component {
return (
<EuiOverlayMask>
<EuiConfirmModal
title={`Confirm Delete ${entity}`}
title={
intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.deleteEntity.confirmModal.modalTitle',
defaultMessage: 'Confirm Delete {entity}',
}, { entity })
}
onCancel={this.closeDeleteConfirmationModal}
onConfirm={() => this.closePopoverAndExecute(deleteIndices)}
cancelButtonText="Cancel"
confirmButtonText="Confirm"
cancelButtonText={
intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.deleteEntity.confirmModal.cancelButtonText',
defaultMessage: 'Cancel',
})
}
confirmButtonText={
intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.deleteEntity.confirmModal.confirmButtonText',
defaultMessage: 'Confirm',
})
}
>
<div>
<p>
You are about to delete {oneIndexSelected ? 'this' : 'these'}{' '}
<FormattedMessage
id="xpack.idxMgmt.indexActionsMenu.deleteEntity.forceMergeDescription"
defaultMessage="You are about to delete {mergedKeyword}"
values={{ mergedKeyword: oneIndexSelected ? 'this' : 'these' }}
/>
{' '}
{entity}:
</p>
<ul>
@ -297,13 +389,23 @@ export class IndexActionsContextMenu extends Component {
))}
</ul>
<EuiCallOut
title="Proceed with caution!"
title={
intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.deleteEntity.proceedWithCautionCallOutTitle',
defaultMessage: 'Proceed with caution!',
})
}
color="warning"
iconType="help"
>
<p>
This operation cannot be undone. Make sure you have appropriate
backups.
<FormattedMessage
id="xpack.idxMgmt.indexActionsMenu.deleteEntity.deleteEntityWarningDescription"
defaultMessage="
This operation cannot be undone. Make sure you have appropriate
backups.
"
/>
</p>
</EuiCallOut>
</div>
@ -318,12 +420,15 @@ export class IndexActionsContextMenu extends Component {
return oneIndexSelected ? 'index' : 'indices';
};
render() {
const { intl } = this.props;
const indexNamesLength = this.props.indexNames.length;
const {
iconSide = 'right',
anchorPosition = 'rightUp',
label = 'Manage ' +
this.props.indexNames.length +
pluralize(' index', this.props.indexNames.length),
label = intl.formatMessage({
id: 'xpack.idxMgmt.indexActionsMenu.manageButtonLabel',
defaultMessage: 'Manage {indexNamesLength, plural, one {index} other {indices}}',
}, { indexNamesLength }),
iconType = 'arrowDown'
} = this.props;
const panels = this.panels();
@ -361,3 +466,5 @@ export class IndexActionsContextMenu extends Component {
);
}
}
export const IndexActionsContextMenu = injectI18n(IndexActionsContextMenuUi);

View file

@ -5,6 +5,8 @@
*/
import React, { Component } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
import { Route } from 'react-router-dom';
import { NoMatch } from '../../../no_match';
import { healthToColor } from '../../../../services';
@ -39,17 +41,33 @@ import {
import { IndexActionsContextMenu } from '../../components';
const HEADERS = {
name: 'Name',
health: 'Health',
status: 'Status',
primary: 'Primaries',
replica: 'Replicas',
documents: 'Docs count',
size: 'Storage size',
primary_size: 'Primary storage size'
name: i18n.translate('xpack.idxMgmt.indexTable.headers.nameHeader', {
defaultMessage: 'Name',
}),
health: i18n.translate('xpack.idxMgmt.indexTable.headers.healthHeader', {
defaultMessage: 'Health',
}),
status: i18n.translate('xpack.idxMgmt.indexTable.headers.statusHeader', {
defaultMessage: 'Status',
}),
primary: i18n.translate('xpack.idxMgmt.indexTable.headers.primaryHeader', {
defaultMessage: 'Primaries',
}),
replica: i18n.translate('xpack.idxMgmt.indexTable.headers.replicaHeader', {
defaultMessage: 'Replicas',
}),
documents: i18n.translate('xpack.idxMgmt.indexTable.headers.documentsHeader', {
defaultMessage: 'Docs count',
}),
size: i18n.translate('xpack.idxMgmt.indexTable.headers.storageSizeHeader', {
defaultMessage: 'Storage size',
}),
primary_size: i18n.translate('xpack.idxMgmt.indexTable.headers.primaryStorageSizeHeader', {
defaultMessage: 'Primary storage size',
})
};
export class IndexTable extends Component {
export class IndexTableUi extends Component {
constructor(props) {
super(props);
@ -209,7 +227,8 @@ export class IndexTable extends Component {
filter,
showSystemIndices,
showSystemIndicesChanged,
indices
indices,
intl,
} = this.props;
const { selectedIndicesMap } = this.state;
const atLeastOneItemSelected = Object.keys(selectedIndicesMap).length > 0;
@ -221,11 +240,21 @@ export class IndexTable extends Component {
<EuiFlexGroup justifyContent="spaceBetween" alignItems="flexEnd">
<EuiFlexItem grow={false}>
<EuiTitle size="l">
<h1>Index management</h1>
<h1>
<FormattedMessage
id="xpack.idxMgmt.indexTable.sectionHeading"
defaultMessage="Index management"
/>
</h1>
</EuiTitle>
<EuiSpacer size="s" />
<EuiText>
<p>Update your Elasticsearch indices individually or in bulk</p>
<p>
<FormattedMessage
id="xpack.idxMgmt.indexTable.sectionDescription"
defaultMessage="Update your Elasticsearch indices individually or in bulk"
/>
</p>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
@ -233,7 +262,12 @@ export class IndexTable extends Component {
id="checkboxShowSystemIndices"
checked={showSystemIndices}
onChange={event => showSystemIndicesChanged(event.target.checked)}
label="Include system indices"
label={
intl.formatMessage({
id: 'xpack.idxMgmt.indexTable.systemIndicesSwitchLabel',
defaultMessage: 'Include system indices',
})
}
/>
</EuiFlexItem>
</EuiFlexGroup>
@ -262,7 +296,12 @@ export class IndexTable extends Component {
filterChanged(event.target.value);
}}
data-test-subj="indexTableFilterInput"
placeholder="Search"
placeholder={
intl.formatMessage({
id: 'xpack.idxMgmt.indexTable.systemIndicesSearchInputPlaceholder',
defaultMessage: 'Search',
})
}
aria-label="Search indices"
/>
</EuiFlexItem>
@ -296,3 +335,5 @@ export class IndexTable extends Component {
);
}
}
export const IndexTable = injectI18n(IndexTableUi);

View file

@ -5,10 +5,14 @@
*/
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
export const NoMatch = () => (
<div>
No indices to show
<FormattedMessage
id="xpack.idxMgmt.noMatch.noIndicesDescription"
defaultMessage="No indices to show"
/>
</div>
);

View file

@ -4,13 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createAction } from "redux-actions";
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { toastNotifications } from 'ui/notify';
import { clearCacheIndices as request } from "../../services";
import { clearRowStatus, reloadIndices } from "../actions";
import { clearCacheIndices as request } from '../../services';
import { clearRowStatus, reloadIndices } from '../actions';
export const clearCacheIndicesStart = createAction(
"INDEX_MANAGEMENT_CLEAR_CACHE_INDICES_START"
'INDEX_MANAGEMENT_CLEAR_CACHE_INDICES_START'
);
export const clearCacheIndices = ({ indexNames }) => async (dispatch) => {
dispatch(clearCacheIndicesStart({ indexNames }));
@ -21,5 +22,10 @@ export const clearCacheIndices = ({ indexNames }) => async (dispatch) => {
return dispatch(clearRowStatus({ indexNames }));
}
dispatch(reloadIndices(indexNames));
toastNotifications.addSuccess(`Successfully cleared cache: [${indexNames.join(", ")}]`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.clearCacheIndicesAction.successMessage', {
defaultMessage: 'Successfully cleared cache: [{indexNames}]',
values: { indexNames: indexNames.join(', ') }
})
);
};

View file

@ -4,13 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createAction } from "redux-actions";
import { closeIndices as request } from "../../services";
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { closeIndices as request } from '../../services';
import { toastNotifications } from 'ui/notify';
import { clearRowStatus, reloadIndices } from "../actions";
import { clearRowStatus, reloadIndices } from '../actions';
export const closeIndicesStart = createAction(
"INDEX_MANAGEMENT_CLOSE_INDICES_START"
'INDEX_MANAGEMENT_CLOSE_INDICES_START'
);
export const closeIndices = ({ indexNames }) => async (dispatch) => {
dispatch(closeIndicesStart({ indexNames }));
@ -21,5 +22,10 @@ export const closeIndices = ({ indexNames }) => async (dispatch) => {
return dispatch(clearRowStatus({ indexNames }));
}
dispatch(reloadIndices(indexNames));
toastNotifications.addSuccess(`Successfully closed: [${indexNames.join(", ")}]`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.closeIndicesAction.successfullyClosedIndicesMessage', {
defaultMessage: 'Successfully closed: [{indexNames}]',
values: { indexNames: indexNames.join(', ') }
})
);
};

View file

@ -4,13 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createAction } from "redux-actions";
import { deleteIndices as request } from "../../services";
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { deleteIndices as request } from '../../services';
import { toastNotifications } from 'ui/notify';
import { clearRowStatus } from "../actions";
import { clearRowStatus } from '../actions';
export const deleteIndicesSuccess = createAction(
"INDEX_MANAGEMENT_DELETE_INDICES_SUCCESS"
'INDEX_MANAGEMENT_DELETE_INDICES_SUCCESS'
);
export const deleteIndices = ({ indexNames }) => async (dispatch) => {
try {
@ -19,6 +20,11 @@ export const deleteIndices = ({ indexNames }) => async (dispatch) => {
toastNotifications.addDanger(error.data.message);
return dispatch(clearRowStatus({ indexNames }));
}
toastNotifications.addSuccess(`Successfully deleted: [${indexNames.join(", ")}]`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.deleteIndicesAction.successfullyDeletedIndicesMessage', {
defaultMessage: 'Successfully deleted: [{indexNames}]',
values: { indexNames: indexNames.join(', ') }
})
);
dispatch(deleteIndicesSuccess({ indexNames }));
};

View file

@ -4,7 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { loadIndexSettings as request } from "../../services";
import { i18n } from '@kbn/i18n';
import { loadIndexSettings as request } from '../../services';
import { loadIndexDataSuccess } from './load_index_data';
import { toastNotifications } from 'ui/notify';
@ -15,7 +16,12 @@ export const editIndexSettings = ({ indexName }) => async (dispatch) => {
} catch (error) {
return toastNotifications.addDanger(error.data.message);
}
toastNotifications.addSuccess(`Successfully saved settings for ${indexName}`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.editIndexSettingsAction.successfullySavedSettingsForIndicesMessage', {
defaultMessage: 'Successfully saved settings for {indexName}',
values: { indexName }
})
);
dispatch(
loadIndexDataSuccess({
data: indexSettings,

View file

@ -4,13 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createAction } from "redux-actions";
import { flushIndices as request } from "../../services";
import { clearRowStatus, reloadIndices } from "../actions";
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { flushIndices as request } from '../../services';
import { clearRowStatus, reloadIndices } from '../actions';
import { toastNotifications } from 'ui/notify';
export const flushIndicesStart = createAction(
"INDEX_MANAGEMENT_FLUSH_INDICES_START"
'INDEX_MANAGEMENT_FLUSH_INDICES_START'
);
export const flushIndices = ({ indexNames }) => async (dispatch) => {
@ -22,5 +23,10 @@ export const flushIndices = ({ indexNames }) => async (dispatch) => {
return dispatch(clearRowStatus({ indexNames }));
}
dispatch(reloadIndices(indexNames));
toastNotifications.addSuccess(`Successfully flushed: [${indexNames.join(", ")}]`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.flushIndicesAction.successfullyFlushedIndicesMessage', {
defaultMessage: 'Successfully flushed: [{indexNames}]',
values: { indexNames: indexNames.join(', ') }
})
);
};

View file

@ -4,13 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createAction } from "redux-actions";
import { forcemergeIndices as request } from "../../services";
import { clearRowStatus, reloadIndices } from "../actions";
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { forcemergeIndices as request } from '../../services';
import { clearRowStatus, reloadIndices } from '../actions';
import { toastNotifications } from 'ui/notify';
export const forcemergeIndicesStart = createAction(
"INDEX_MANAGEMENT_FORCEMERGE_INDICES_START"
'INDEX_MANAGEMENT_FORCEMERGE_INDICES_START'
);
export const forcemergeIndices = ({ indexNames, maxNumSegments }) => async (dispatch) => {
@ -22,5 +23,10 @@ export const forcemergeIndices = ({ indexNames, maxNumSegments }) => async (disp
return dispatch(clearRowStatus({ indexNames }));
}
dispatch(reloadIndices(indexNames));
toastNotifications.addSuccess(`Successfully force merged: [${indexNames.join(", ")}]`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.forceMergeIndicesAction.successfullyForceMergedIndicesMessage', {
defaultMessage: 'Successfully force merged: [{indexNames}]',
values: { indexNames: indexNames.join(', ') }
})
);
};

View file

@ -4,13 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createAction } from "redux-actions";
import { openIndices as request } from "../../services";
import { clearRowStatus, reloadIndices } from "../actions";
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { openIndices as request } from '../../services';
import { clearRowStatus, reloadIndices } from '../actions';
import { toastNotifications } from 'ui/notify';
export const openIndicesStart = createAction(
"INDEX_MANAGEMENT_OPEN_INDICES_START"
'INDEX_MANAGEMENT_OPEN_INDICES_START'
);
export const openIndices = ({ indexNames }) => async (dispatch) => {
@ -22,5 +23,10 @@ export const openIndices = ({ indexNames }) => async (dispatch) => {
return dispatch(clearRowStatus({ indexNames }));
}
dispatch(reloadIndices(indexNames));
toastNotifications.addSuccess(`Successfully opened: [${indexNames.join(", ")}]`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.openIndicesAction.successfullyOpenedIndicesMessage', {
defaultMessage: 'Successfully opened: [{indexNames}]',
values: { indexNames: indexNames.join(', ') }
})
);
};

View file

@ -4,10 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createAction } from "redux-actions";
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { refreshIndices as request } from "../../services";
import { clearRowStatus, reloadIndices } from "../actions";
import { refreshIndices as request } from '../../services';
import { clearRowStatus, reloadIndices } from '../actions';
import { toastNotifications } from 'ui/notify';
export const refreshIndicesStart = createAction(
@ -22,5 +23,10 @@ export const refreshIndices = ({ indexNames }) => async (dispatch) => {
return dispatch(clearRowStatus({ indexNames }));
}
dispatch(reloadIndices(indexNames));
toastNotifications.addSuccess(`Successfully refreshed: [${indexNames.join(", ")}]`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.refreshIndicesAction.successfullyRefreshedIndicesMessage', {
defaultMessage: 'Successfully refreshed: [{indexNames}]',
values: { indexNames: indexNames.join(', ') }
})
);
};

View file

@ -5,6 +5,7 @@
*/
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { getIndexNamesForCurrentPage } from '../selectors';
import { reloadIndices as request } from '../../services';
import { toastNotifications } from 'ui/notify';
@ -21,6 +22,10 @@ export const reloadIndices = (indexNames) => async (dispatch, getState) => {
if (indices && indices.length > 0) {
return dispatch(reloadIndicesSuccess({ indices }));
} else {
return toastNotifications.addWarning('Failed to refresh current page of indices.');
return toastNotifications.addWarning(
i18n.translate('xpack.idxMgmt.reloadIndicesAction.indicesPageRefreshFailureMessage', {
defaultMessage: 'Failed to refresh current page of indices.',
})
);
}
};

View file

@ -4,8 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createAction } from "redux-actions";
import { updateIndexSettings as request } from "../../services";
import { createAction } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { updateIndexSettings as request } from '../../services';
import { reloadIndices } from './reload_indices';
import { toastNotifications } from 'ui/notify';
@ -33,5 +34,10 @@ export const updateIndexSettings = ({
}
dispatch(updateIndexSettingsSuccess());
dispatch(reloadIndices([ indexName ]));
toastNotifications.addSuccess(`Successfully updated settings for index ${indexName}`);
toastNotifications.addSuccess(
i18n.translate('xpack.idxMgmt.updateIndexSettingsAction.settingsSuccessUpdateMessage', {
defaultMessage: 'Successfully updated settings for index {indexName}',
values: { indexName }
})
);
};

View file

@ -0,0 +1,45 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import PropTypes from 'prop-types';
import React from 'react';
import { mount } from 'enzyme'; // eslint-disable-line import/no-extraneous-dependencies
import { intl } from './mocks/intl';
/**
* Creates the wrapper instance with provided intl object into context
*
* @param node The React element or cheerio wrapper
* @param options properties to pass into mount wrapper
* @return The wrapper instance around the rendered output with intl object in context
*/
export function mountWithIntl(node, { context = {}, childContextTypes = {}, ...props } = {}) {
if (!node) {
throw new Error(`First argument should be cheerio object or React element, not ${node}`);
}
const clonedNode = React.cloneElement(node, { intl });
const options = {
context: {
...context,
intl,
},
childContextTypes: {
...childContextTypes,
intl: PropTypes.any,
},
...props,
};
if (React.isValidElement(node)) {
return mount(clonedNode, options);
}
return clonedNode.mount(options);
}
export { intl };

View file

@ -0,0 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/* global jest */
export const intl = {
formatMessage: jest.fn().mockImplementation(({ defaultMessage }) => defaultMessage),
formatDate: jest.fn().mockImplementation(value => value),
formatTime: jest.fn().mockImplementation(value => value),
formatRelative: jest.fn().mockImplementation(value => value),
formatNumber: jest.fn().mockImplementation(value => value),
formatPlural: jest.fn().mockImplementation(value => value),
formatHTMLMessage: jest.fn().mockImplementation(({ defaultMessage }) => defaultMessage),
now: jest.fn().mockImplementation(() => new Date(1531834573179)),
textComponent: 'span'
};

View file

@ -59,6 +59,10 @@
version "0.0.0"
uid ""
"@kbn/i18n@link:../packages/kbn-i18n":
version "0.0.0"
uid ""
"@kbn/plugin-helpers@link:../packages/kbn-plugin-helpers":
version "0.0.0"
uid ""
@ -3544,6 +3548,26 @@ interpret@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
intl-format-cache@^2.0.5, intl-format-cache@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-2.1.0.tgz#04a369fecbfad6da6005bae1f14333332dcf9316"
intl-messageformat-parser@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075"
intl-messageformat@^2.0.0, intl-messageformat@^2.1.0, intl-messageformat@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc"
dependencies:
intl-messageformat-parser "1.4.0"
intl-relativeformat@^2.0.0, intl-relativeformat@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz#010f1105802251f40ac47d0e3e1a201348a255df"
dependencies:
intl-messageformat "^2.0.0"
into-stream@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"
@ -3557,6 +3581,12 @@ invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
dependencies:
loose-envify "^1.0.0"
invariant@^2.1.1:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
dependencies:
loose-envify "^1.0.0"
invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
@ -4362,6 +4392,12 @@ json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
dependencies:
minimist "^1.2.0"
jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
@ -6149,6 +6185,15 @@ react-input-autosize@^2.1.2, react-input-autosize@^2.2.1:
dependencies:
prop-types "^15.5.8"
react-intl@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.4.0.tgz#66c14dc9df9a73b2fbbfbd6021726e80a613eb15"
dependencies:
intl-format-cache "^2.0.5"
intl-messageformat "^2.1.0"
intl-relativeformat "^2.0.0"
invariant "^2.1.1"
react-is@^16.3.1:
version "16.4.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.1.tgz#d624c4650d2c65dbd52c72622bbf389435d9776e"