* fix tests and update snapshots * fix id names * fix test and update snapshots * Update unit test snapshots * fix issues * Update snapshots * Fix issues
This commit is contained in:
parent
cf149f9d60
commit
cd81a9e9d8
|
@ -4,6 +4,7 @@
|
|||
"inputControl":"src/core_plugins/input_control_vis",
|
||||
"kbn": "src/core_plugins/kibana",
|
||||
"kbnVislibVisTypes": "src/core_plugins/kbn_vislib_vis_types",
|
||||
"kbn.management.objects": "src/core_plugins/kibana/public/management",
|
||||
"markdownVis": "src/core_plugins/markdown_vis",
|
||||
"metricVis": "src/core_plugins/metric_vis",
|
||||
"statusPage": "src/core_plugins/status_page",
|
||||
|
|
|
@ -28,6 +28,7 @@ import React from 'react';
|
|||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { ObjectsTable } from './components/objects_table';
|
||||
import { getInAppUrl } from './lib/get_in_app_url';
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
|
||||
const REACT_OBJECTS_TABLE_DOM_ELEMENT_ID = 'reactSavedObjectsTable';
|
||||
|
||||
|
@ -52,31 +53,33 @@ function updateObjectsTable($scope, $injector) {
|
|||
}
|
||||
|
||||
render(
|
||||
<ObjectsTable
|
||||
savedObjectsClient={savedObjectsClient}
|
||||
services={services}
|
||||
indexPatterns={indexPatterns}
|
||||
$http={$http}
|
||||
perPageConfig={config.get('savedObjects:perPage')}
|
||||
basePath={chrome.getBasePath()}
|
||||
newIndexPatternUrl={kbnUrl.eval('#/management/kibana/index')}
|
||||
getEditUrl={(id, type) => {
|
||||
if (type === 'index-pattern' || type === 'indexPatterns') {
|
||||
return kbnUrl.eval(`#/management/kibana/indices/${id}`);
|
||||
}
|
||||
const serviceName = typeToServiceName(type);
|
||||
if (!serviceName) {
|
||||
toastNotifications.addWarning(`Unknown saved object type: ${type}`);
|
||||
return null;
|
||||
}
|
||||
<I18nProvider>
|
||||
<ObjectsTable
|
||||
savedObjectsClient={savedObjectsClient}
|
||||
services={services}
|
||||
indexPatterns={indexPatterns}
|
||||
$http={$http}
|
||||
perPageConfig={config.get('savedObjects:perPage')}
|
||||
basePath={chrome.getBasePath()}
|
||||
newIndexPatternUrl={kbnUrl.eval('#/management/kibana/index')}
|
||||
getEditUrl={(id, type) => {
|
||||
if (type === 'index-pattern' || type === 'indexPatterns') {
|
||||
return kbnUrl.eval(`#/management/kibana/indices/${id}`);
|
||||
}
|
||||
const serviceName = typeToServiceName(type);
|
||||
if (!serviceName) {
|
||||
toastNotifications.addWarning(`Unknown saved object type: ${type}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return kbnUrl.eval(`#/management/kibana/objects/${serviceName}/${id}`);
|
||||
}}
|
||||
goInApp={(id, type) => {
|
||||
kbnUrl.change(getInAppUrl(id, type));
|
||||
$scope.$apply();
|
||||
}}
|
||||
/>,
|
||||
return kbnUrl.eval(`#/management/kibana/objects/${serviceName}/${id}`);
|
||||
}}
|
||||
goInApp={(id, type) => {
|
||||
kbnUrl.change(getInAppUrl(id, type));
|
||||
$scope.$apply();
|
||||
}}
|
||||
/>
|
||||
</I18nProvider>,
|
||||
node,
|
||||
);
|
||||
});
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
<!-- Header -->
|
||||
<div class="kuiViewContentItem kuiBar kuiVerticalRhythm">
|
||||
<div class="kuiBarSection">
|
||||
<h1 class="kuiTitle">
|
||||
Edit {{ title }}
|
||||
</h1>
|
||||
<h1
|
||||
class="kuiTitle"
|
||||
i18n-id="kbn.management.objects.view.editItemTitle"
|
||||
i18n-default-message="Edit {title}"
|
||||
i18n-values="{ title }"
|
||||
></h1>
|
||||
</div>
|
||||
|
||||
<div class="kuiBarSection">
|
||||
|
@ -15,7 +18,11 @@
|
|||
>
|
||||
<span class="kuiButton__inner">
|
||||
<span class="kuiButton__icon kuiIcon fa-eye"></span>
|
||||
<span>View {{ title }}</span>
|
||||
<span
|
||||
i18n-id="kbn.management.objects.view.viewItemButtonLabel"
|
||||
i18n-default-message="View {title}"
|
||||
i18n-values="{ title }"
|
||||
></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
|
@ -25,7 +32,11 @@
|
|||
>
|
||||
<span class="kuiButton__inner">
|
||||
<span class="kuiButton__icon kuiIcon fa-trash-o"></span>
|
||||
<span>Delete {{ title }}</span>
|
||||
<span
|
||||
i18n-id="kbn.management.objects.view.deleteItemButtonLabel"
|
||||
i18n-default-message="Delete {title}"
|
||||
i18n-values="{ title }"
|
||||
></span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -39,36 +50,40 @@
|
|||
<div class="kuiInfoPanel kuiInfoPanel--error">
|
||||
<div class="kuiInfoPanelHeader">
|
||||
<span class="kuiInfoPanelHeader__icon kuiIcon kuiIcon--error fa-warning"></span>
|
||||
<span class="kuiInfoPanelHeader__title">
|
||||
There is a problem with this saved object
|
||||
</span>
|
||||
<span
|
||||
class="kuiInfoPanelHeader__title"
|
||||
i18n-id="kbn.management.objects.view.savedObjectProblemErrorMessage"
|
||||
i18n-default-message="There is a problem with this saved object"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div class="kuiInfoPanelBody">
|
||||
<div
|
||||
class="kuiInfoPanelBody__message"
|
||||
ng-if="notFound === 'search'"
|
||||
>
|
||||
The saved search associated with this object no longer exists.
|
||||
</div>
|
||||
i18n-id="kbn.management.objects.view.savedSearchDoesNotExistErrorMessage"
|
||||
i18n-default-message="The saved search associated with this object no longer exists."
|
||||
></div>
|
||||
|
||||
<div
|
||||
class="kuiInfoPanelBody__message"
|
||||
ng-if="notFound === 'index-pattern'"
|
||||
>
|
||||
The index pattern associated with this object no longer exists.
|
||||
</div>
|
||||
i18n-id="kbn.management.objects.view.indexPatternDoesNotExistErrorMessage"
|
||||
i18n-default-message="The index pattern associated with this object no longer exists."
|
||||
></div>
|
||||
|
||||
<div
|
||||
class="kuiInfoPanelBody__message"
|
||||
ng-if="notFound === 'index-pattern-field'"
|
||||
>
|
||||
A field associated with this object no longer exists in the index pattern.
|
||||
</div>
|
||||
i18n-id="kbn.management.objects.view.fieldDoesNotExistErrorMessage"
|
||||
i18n-default-message="A field associated with this object no longer exists in the index pattern."
|
||||
></div>
|
||||
|
||||
<div class="kuiInfoPanelBody__message">
|
||||
If you know what this error means, go ahead and fix it — otherwise click the delete button above.
|
||||
</div>
|
||||
<div
|
||||
class="kuiInfoPanelBody__message"
|
||||
i18n-id="kbn.management.objects.view.howToFixErrorDescription"
|
||||
i18n-default-message="If you know what this error means, go ahead and fix it — otherwise click the delete button above."
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -78,14 +93,19 @@
|
|||
<div class="kuiInfoPanel kuiInfoPanel--warning">
|
||||
<div class="kuiInfoPanelHeader">
|
||||
<span class="kuiInfoPanelHeader__icon kuiIcon kuiIcon--warning fa-bolt"></span>
|
||||
<span class="kuiInfoPanelHeader__title">
|
||||
Proceed with caution!
|
||||
</span>
|
||||
<span
|
||||
class="kuiInfoPanelHeader__title"
|
||||
i18n-id="kbn.management.objects.view.howToModifyObjectTitle"
|
||||
i18n-default-message="Proceed with caution!"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div class="kuiInfoPanelBody">
|
||||
<div class="kuiInfoPanelBody__message">
|
||||
Modifying objects is for advanced users only. Object properties are not validated and invalid objects could cause errors, data loss, or worse. Unless someone with intimate knowledge of the code told you to be in here, you probably shouldn’t be.
|
||||
<div
|
||||
class="kuiInfoPanelBody__message"
|
||||
i18n-id="kbn.management.objects.view.howToModifyObjectDescription"
|
||||
i18n-default-message=" Modifying objects is for advanced users only. Object properties are not validated and invalid objects could cause errors, data loss, or worse. Unless someone with intimate knowledge of the code told you to be in here, you probably shouldn’t be."
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -143,20 +163,21 @@
|
|||
<div class="kuiButtonGroup">
|
||||
<button
|
||||
class="kuiButton kuiButton--primary"
|
||||
aria-label="Save {{ title }} Object"
|
||||
aria-label="{{ 'kbn.management.objects.view.saveButtonAriaLabel' | i18n: { defaultMessage: 'Save { title } Object', values: { title } } }}"
|
||||
ng-click="submit()"
|
||||
ng-disabled="objectForm.$invalid || aceInvalidEditors.length !==0"
|
||||
>
|
||||
Save {{ title }} Object
|
||||
</button>
|
||||
i18n-id="kbn.management.objects.view.saveButtonLabel"
|
||||
i18n-default-message="Save { title } Object"
|
||||
i18n-values="{ title }"
|
||||
></button>
|
||||
|
||||
<button
|
||||
class="kuiButton kuiButton--basic"
|
||||
aria-label="Cancel"
|
||||
aria-label="{{ 'kbn.management.objects.view.cancelButtonAriaLabel' | i18n: { defaultMessage: 'Cancel'} }}"
|
||||
ng-click="cancel()"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
i18n-id="kbn.management.objects.view.cancelButtonLabel"
|
||||
i18n-default-message="Cancel"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</kbn-management-objects-view>
|
||||
|
|
|
@ -38,7 +38,7 @@ uiRoutes
|
|||
});
|
||||
|
||||
uiModules.get('apps/management')
|
||||
.directive('kbnManagementObjectsView', function (kbnIndex, confirmModal) {
|
||||
.directive('kbnManagementObjectsView', function (kbnIndex, confirmModal, i18n) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: function ($scope, $injector, $routeParams, $location, $window, $rootScope, Private) {
|
||||
|
@ -199,11 +199,17 @@ uiModules.get('apps/management')
|
|||
}
|
||||
const confirmModalOptions = {
|
||||
onConfirm: doDelete,
|
||||
confirmButtonText: 'Delete',
|
||||
title: 'Delete saved Kibana object?'
|
||||
confirmButtonText: i18n('kbn.management.objects.confirmModalOptions.deleteButtonLabel', {
|
||||
defaultMessage: 'Delete',
|
||||
}),
|
||||
title: i18n('kbn.management.objects.confirmModalOptions.modalTitle', {
|
||||
defaultMessage: 'Delete saved Kibana object?'
|
||||
}),
|
||||
};
|
||||
confirmModal(
|
||||
`You can't recover deleted objects`,
|
||||
i18n('kbn.management.objects.confirmModalOptions.modalDescription', {
|
||||
defaultMessage: 'You can\'t recover deleted objects',
|
||||
}),
|
||||
confirmModalOptions
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,15 +3,37 @@
|
|||
exports[`ObjectsTable delete should show a confirm modal 1`] = `
|
||||
<EuiConfirmModal
|
||||
buttonColor="primary"
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Delete"
|
||||
cancelButtonText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
id="kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModal.cancelButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
confirmButtonText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete"
|
||||
id="kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModal.deleteButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
defaultFocusedButton="confirm"
|
||||
onCancel={[Function]}
|
||||
onConfirm={[Function]}
|
||||
title="Delete saved objects"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete saved objects"
|
||||
id="kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModalTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
This action will delete the following saved objects:
|
||||
<FormattedMessage
|
||||
defaultMessage="This action will delete the following saved objects:"
|
||||
id="kbn.management.objects.deleteSavedObjectsConfirmModalDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
|
@ -50,15 +72,41 @@ exports[`ObjectsTable delete should show a confirm modal 1`] = `
|
|||
exports[`ObjectsTable export should allow the user to choose when exporting all 1`] = `
|
||||
<EuiConfirmModal
|
||||
buttonColor="primary"
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Export All"
|
||||
cancelButtonText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
id="kbn.management.objects.objectsTable.exportObjectsConfirmModal.cancelButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
confirmButtonText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Export All"
|
||||
id="kbn.management.objects.objectsTable.exportObjectsConfirmModal.exportAllButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
defaultFocusedButton="confirm"
|
||||
onCancel={[Function]}
|
||||
onConfirm={[Function]}
|
||||
title="Export 4 objects"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Export {filteredItemCount, plural, one{# object} other {# objects}}"
|
||||
id="kbn.management.objects.objectsTable.exportObjectsConfirmModalTitle"
|
||||
values={
|
||||
Object {
|
||||
"filteredItemCount": 4,
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Select which types to export. The number in parentheses indicates how many of this type are available to export.
|
||||
<FormattedMessage
|
||||
defaultMessage="Select which types to export. The number in parentheses indicates how many of this type are available to export."
|
||||
id="kbn.management.objects.objectsTable.exportObjectsConfirmModalDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<EuiCheckboxGroup
|
||||
idToSelectedMap={
|
||||
|
@ -95,7 +143,7 @@ exports[`ObjectsTable export should allow the user to choose when exporting all
|
|||
`;
|
||||
|
||||
exports[`ObjectsTable import should show the flyout 1`] = `
|
||||
<Flyout
|
||||
<InjectIntl(FlyoutUI)
|
||||
close={[Function]}
|
||||
done={[Function]}
|
||||
indexPatterns={
|
||||
|
@ -111,7 +159,7 @@ exports[`ObjectsTable import should show the flyout 1`] = `
|
|||
`;
|
||||
|
||||
exports[`ObjectsTable relationships should show the flyout 1`] = `
|
||||
<Relationships
|
||||
<InjectIntl(RelationshipsUI)
|
||||
close={[Function]}
|
||||
getEditUrl={[Function]}
|
||||
getRelationships={[Function]}
|
||||
|
@ -150,7 +198,7 @@ exports[`ObjectsTable should render normally 1`] = `
|
|||
<EuiSpacer
|
||||
size="xs"
|
||||
/>
|
||||
<Table
|
||||
<InjectIntl(TableUI)
|
||||
filterOptions={
|
||||
Array [
|
||||
Object {
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
import { ObjectsTable, INCLUDED_TYPES } from '../objects_table';
|
||||
import { Flyout } from '../components/flyout/';
|
||||
import { Relationships } from '../components/relationships/';
|
||||
|
||||
jest.mock('../components/header', () => ({
|
||||
Header: () => 'Header',
|
||||
|
@ -157,8 +159,8 @@ describe('ObjectsTable', () => {
|
|||
});
|
||||
|
||||
it('should render normally', async () => {
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
perPageConfig={15}
|
||||
/>
|
||||
|
@ -194,8 +196,8 @@ describe('ObjectsTable', () => {
|
|||
|
||||
const { retrieveAndExportDocs } = require('../../../lib/retrieve_and_export_docs');
|
||||
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
savedObjectsClient={mockSavedObjectsClient}
|
||||
/>
|
||||
|
@ -216,8 +218,8 @@ describe('ObjectsTable', () => {
|
|||
});
|
||||
|
||||
it('should allow the user to choose when exporting all', async () => {
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
@ -236,8 +238,8 @@ describe('ObjectsTable', () => {
|
|||
it('should export all', async () => {
|
||||
const { scanAllTypes } = require('../../../lib/scan_all_types');
|
||||
const { saveToFile } = require('../../../lib/save_to_file');
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
@ -259,8 +261,8 @@ describe('ObjectsTable', () => {
|
|||
|
||||
describe('import', () => {
|
||||
it('should show the flyout', async () => {
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
@ -273,12 +275,12 @@ describe('ObjectsTable', () => {
|
|||
component.instance().showImportFlyout();
|
||||
component.update();
|
||||
|
||||
expect(component.find('Flyout')).toMatchSnapshot();
|
||||
expect(component.find(Flyout)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should hide the flyout', async () => {
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
@ -291,7 +293,7 @@ describe('ObjectsTable', () => {
|
|||
component.instance().hideImportFlyout();
|
||||
component.update();
|
||||
|
||||
expect(component.find('Flyout').length).toBe(0);
|
||||
expect(component.find(Flyout).length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -299,8 +301,8 @@ describe('ObjectsTable', () => {
|
|||
it('should fetch relationships', async () => {
|
||||
const { getRelationships } = require('../../../lib/get_relationships');
|
||||
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
@ -315,8 +317,8 @@ describe('ObjectsTable', () => {
|
|||
});
|
||||
|
||||
it('should show the flyout', async () => {
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
@ -329,15 +331,15 @@ describe('ObjectsTable', () => {
|
|||
component.instance().onShowRelationships('1', 'search', 'MySearch');
|
||||
component.update();
|
||||
|
||||
expect(component.find('Relationships')).toMatchSnapshot();
|
||||
expect(component.find(Relationships)).toMatchSnapshot();
|
||||
expect(component.state('relationshipId')).toBe('1');
|
||||
expect(component.state('relationshipType')).toBe('search');
|
||||
expect(component.state('relationshipTitle')).toBe('MySearch');
|
||||
});
|
||||
|
||||
it('should hide the flyout', async () => {
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
@ -350,7 +352,7 @@ describe('ObjectsTable', () => {
|
|||
component.instance().onHideRelationships();
|
||||
component.update();
|
||||
|
||||
expect(component.find('Relationships').length).toBe(0);
|
||||
expect(component.find(Relationships).length).toBe(0);
|
||||
expect(component.state('relationshipId')).toBe(undefined);
|
||||
expect(component.state('relationshipType')).toBe(undefined);
|
||||
expect(component.state('relationshipTitle')).toBe(undefined);
|
||||
|
@ -359,8 +361,8 @@ describe('ObjectsTable', () => {
|
|||
|
||||
describe('delete', () => {
|
||||
it('should show a confirm modal', async () => {
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
@ -403,8 +405,8 @@ describe('ObjectsTable', () => {
|
|||
delete: jest.fn(),
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<ObjectsTable
|
||||
const component = shallowWithIntl(
|
||||
<ObjectsTable.WrappedComponent
|
||||
{...defaultProps}
|
||||
savedObjectsClient={mockSavedObjectsClient}
|
||||
/>
|
||||
|
|
|
@ -16,7 +16,11 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = `
|
|||
size="m"
|
||||
>
|
||||
<h2>
|
||||
Import saved objects
|
||||
<FormattedMessage
|
||||
defaultMessage="Import saved objects"
|
||||
id="kbn.management.objects.objectsTable.flyout.importSavedObjectTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<React.Fragment>
|
||||
|
@ -27,20 +31,34 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = `
|
|||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title="Index Pattern Conflicts"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Index Pattern Conflicts"
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
The following saved objects use index patterns that do not exist. Please select the index patterns you'd like re-associated with them. You can
|
||||
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href=""
|
||||
type="button"
|
||||
>
|
||||
create a new index pattern
|
||||
</EuiLink>
|
||||
|
||||
if necessary.
|
||||
<FormattedMessage
|
||||
defaultMessage="The following saved objects use index patterns that do not exist. Please select the index patterns you'd like re-associated with them. You can {indexPatternLink} if necessary."
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsDescription"
|
||||
values={
|
||||
Object {
|
||||
"indexPatternLink": <EuiLink
|
||||
color="primary"
|
||||
href=""
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="create a new index pattern"
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsCalloutLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</React.Fragment>
|
||||
|
@ -123,7 +141,11 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Cancel
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
id="kbn.management.objects.objectsTable.flyout.import.cancelButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -140,7 +162,11 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Confirm all changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Confirm all changes"
|
||||
id="kbn.management.objects.objectsTable.flyout.importSuccessful.confirmAllChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -153,7 +179,13 @@ exports[`Flyout conflicts should handle errors 1`] = `
|
|||
color="danger"
|
||||
iconType="cross"
|
||||
size="m"
|
||||
title="Sorry, there was an error"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Sorry, there was an error"
|
||||
id="kbn.management.objects.objectsTable.flyout.errorCalloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
foobar
|
||||
|
@ -177,7 +209,11 @@ exports[`Flyout should render import step 1`] = `
|
|||
size="m"
|
||||
>
|
||||
<h2>
|
||||
Import saved objects
|
||||
<FormattedMessage
|
||||
defaultMessage="Import saved objects"
|
||||
id="kbn.management.objects.objectsTable.flyout.importSavedObjectTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
|
@ -187,11 +223,23 @@ exports[`Flyout should render import step 1`] = `
|
|||
describedByIds={Array []}
|
||||
fullWidth={false}
|
||||
hasEmptyLabelSpace={false}
|
||||
label="Please select a JSON file to import"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Please select a JSON file to import"
|
||||
id="kbn.management.objects.objectsTable.flyout.selectFileToImportFormRowLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiFilePicker
|
||||
compressed={false}
|
||||
initialPromptText="Import"
|
||||
initialPromptText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Import"
|
||||
id="kbn.management.objects.objectsTable.flyout.importPromptText"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[Function]}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
@ -203,7 +251,13 @@ exports[`Flyout should render import step 1`] = `
|
|||
<EuiSwitch
|
||||
checked={true}
|
||||
data-test-subj="importSavedObjectsOverwriteToggle"
|
||||
label="Automatically overwrite all saved objects?"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Automatically overwrite all saved objects?"
|
||||
id="kbn.management.objects.objectsTable.flyout.overwriteSavedObjectsLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
name="overwriteAll"
|
||||
onChange={[Function]}
|
||||
/>
|
||||
|
@ -231,7 +285,11 @@ exports[`Flyout should render import step 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Cancel
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
id="kbn.management.objects.objectsTable.flyout.import.cancelButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -248,7 +306,11 @@ exports[`Flyout should render import step 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Import
|
||||
<FormattedMessage
|
||||
defaultMessage="Import"
|
||||
id="kbn.management.objects.objectsTable.flyout.import.confirmButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
import { Flyout } from '../flyout';
|
||||
|
||||
|
@ -66,7 +66,7 @@ const mockFile = {
|
|||
|
||||
describe('Flyout', () => {
|
||||
it('should render import step', async () => {
|
||||
const component = shallow(<Flyout {...defaultProps} />);
|
||||
const component = shallowWithIntl(<Flyout.WrappedComponent {...defaultProps} />);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
|
@ -77,7 +77,7 @@ describe('Flyout', () => {
|
|||
});
|
||||
|
||||
it('should toggle the overwrite all control', async () => {
|
||||
const component = shallow(<Flyout {...defaultProps} />);
|
||||
const component = shallowWithIntl(<Flyout.WrappedComponent {...defaultProps} />);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
|
@ -90,7 +90,7 @@ describe('Flyout', () => {
|
|||
});
|
||||
|
||||
it('should allow picking a file', async () => {
|
||||
const component = shallow(<Flyout {...defaultProps} />);
|
||||
const component = shallowWithIntl(<Flyout.WrappedComponent {...defaultProps} />);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
|
@ -104,7 +104,7 @@ describe('Flyout', () => {
|
|||
|
||||
it('should handle invalid files', async () => {
|
||||
const { importFile } = require('../../../../../lib/import_file');
|
||||
const component = shallow(<Flyout {...defaultProps} />);
|
||||
const component = shallowWithIntl(<Flyout.WrappedComponent {...defaultProps} />);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
|
@ -183,7 +183,7 @@ describe('Flyout', () => {
|
|||
});
|
||||
|
||||
it('should figure out conflicts', async () => {
|
||||
const component = shallow(<Flyout {...defaultProps} />);
|
||||
const component = shallowWithIntl(<Flyout.WrappedComponent {...defaultProps} />);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
|
@ -226,7 +226,7 @@ describe('Flyout', () => {
|
|||
});
|
||||
|
||||
it('should allow conflict resolution', async () => {
|
||||
const component = shallow(<Flyout {...defaultProps} />);
|
||||
const component = shallowWithIntl(<Flyout.WrappedComponent {...defaultProps} />);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
|
@ -270,7 +270,7 @@ describe('Flyout', () => {
|
|||
});
|
||||
|
||||
it('should handle errors', async () => {
|
||||
const component = shallow(<Flyout {...defaultProps} />);
|
||||
const component = shallowWithIntl(<Flyout.WrappedComponent {...defaultProps} />);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
|
|
|
@ -50,8 +50,9 @@ import {
|
|||
saveObjects,
|
||||
} from '../../../../lib/resolve_saved_objects';
|
||||
import { INCLUDED_TYPES } from '../../objects_table';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
export class Flyout extends Component {
|
||||
class FlyoutUI extends Component {
|
||||
static propTypes = {
|
||||
close: PropTypes.func.isRequired,
|
||||
done: PropTypes.func.isRequired,
|
||||
|
@ -102,7 +103,7 @@ export class Flyout extends Component {
|
|||
};
|
||||
|
||||
import = async () => {
|
||||
const { services, indexPatterns } = this.props;
|
||||
const { services, indexPatterns, intl } = this.props;
|
||||
const { file, isOverwriteAllChecked } = this.state;
|
||||
|
||||
this.setState({ isLoading: true, error: undefined });
|
||||
|
@ -114,7 +115,10 @@ export class Flyout extends Component {
|
|||
} catch (e) {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
error: 'The file could not be processed.',
|
||||
error: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.importFileErrorMessage',
|
||||
defaultMessage: 'The file could not be processed.',
|
||||
}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -122,7 +126,10 @@ export class Flyout extends Component {
|
|||
if (!Array.isArray(contents)) {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
error: 'Saved objects file format is invalid and cannot be imported.',
|
||||
error: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.invalidFormatOfImportedFileErrorMessage',
|
||||
defaultMessage: 'Saved objects file format is invalid and cannot be imported.',
|
||||
}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -211,7 +218,7 @@ export class Flyout extends Component {
|
|||
failedImports
|
||||
} = this.state;
|
||||
|
||||
const { services, indexPatterns } = this.props;
|
||||
const { services, indexPatterns, intl } = this.props;
|
||||
|
||||
this.setState({
|
||||
error: undefined,
|
||||
|
@ -226,7 +233,12 @@ export class Flyout extends Component {
|
|||
const resolutions = this.resolutions;
|
||||
|
||||
// Do not Promise.all these calls as the order matters
|
||||
this.setState({ loadingMessage: 'Resolving conflicts...' });
|
||||
this.setState({
|
||||
loadingMessage: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.confirmImport.resolvingConflictsLoadingMessage',
|
||||
defaultMessage: 'Resolving conflicts…',
|
||||
}),
|
||||
});
|
||||
if (resolutions.length) {
|
||||
importCount += await resolveIndexPatternConflicts(
|
||||
resolutions,
|
||||
|
@ -234,13 +246,21 @@ export class Flyout extends Component {
|
|||
isOverwriteAllChecked
|
||||
);
|
||||
}
|
||||
this.setState({ loadingMessage: 'Saving conflicts...' });
|
||||
this.setState({
|
||||
loadingMessage: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.confirmImport.savingConflictsLoadingMessage',
|
||||
defaultMessage: 'Saving conflicts…',
|
||||
}),
|
||||
});
|
||||
importCount += await saveObjects(
|
||||
conflictedSavedObjectsLinkedToSavedSearches,
|
||||
isOverwriteAllChecked
|
||||
);
|
||||
this.setState({
|
||||
loadingMessage: 'Ensure saved searches are linked properly...',
|
||||
loadingMessage: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.confirmImport.savedSearchAreLinkedProperlyLoadingMessage',
|
||||
defaultMessage: 'Ensure saved searches are linked properly…',
|
||||
}),
|
||||
});
|
||||
importCount += await resolveSavedSearches(
|
||||
conflictedSearchDocs,
|
||||
|
@ -249,7 +269,10 @@ export class Flyout extends Component {
|
|||
isOverwriteAllChecked
|
||||
);
|
||||
this.setState({
|
||||
loadingMessage: 'Retrying failed objects...',
|
||||
loadingMessage: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.confirmImport.retryingFailedObjectsLoadingMessage',
|
||||
defaultMessage: 'Retrying failed objects…',
|
||||
}),
|
||||
});
|
||||
importCount += await saveObjects(
|
||||
failedImports.map(({ obj }) => obj),
|
||||
|
@ -293,6 +316,7 @@ export class Flyout extends Component {
|
|||
|
||||
renderConflicts() {
|
||||
const { conflicts } = this.state;
|
||||
const { intl } = this.props;
|
||||
|
||||
if (!conflicts) {
|
||||
return null;
|
||||
|
@ -301,22 +325,40 @@ export class Flyout extends Component {
|
|||
const columns = [
|
||||
{
|
||||
field: 'existingIndexPatternId',
|
||||
name: 'ID',
|
||||
description: `ID of the index pattern`,
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.renderConflicts.columnIdName',
|
||||
defaultMessage: 'ID',
|
||||
}),
|
||||
description: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.renderConflicts.columnIdDescription',
|
||||
defaultMessage: 'ID of the index pattern',
|
||||
}),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'list',
|
||||
name: 'Count',
|
||||
description: `How many affected objects`,
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.renderConflicts.columnCountName',
|
||||
defaultMessage: 'Count',
|
||||
}),
|
||||
description: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.renderConflicts.columnCountDescription',
|
||||
defaultMessage: 'How many affected objects',
|
||||
}),
|
||||
render: list => {
|
||||
return <Fragment>{list.length}</Fragment>;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'list',
|
||||
name: 'Sample of affected objects',
|
||||
description: `Sample of affected objects`,
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.renderConflicts.columnSampleOfAffectedObjectsName',
|
||||
defaultMessage: 'Sample of affected objects',
|
||||
}),
|
||||
description: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.renderConflicts.columnSampleOfAffectedObjectsDescription',
|
||||
defaultMessage: 'Sample of affected objects',
|
||||
}),
|
||||
render: list => {
|
||||
return (
|
||||
<ul style={{ listStyle: 'none' }}>
|
||||
|
@ -327,7 +369,10 @@ export class Flyout extends Component {
|
|||
},
|
||||
{
|
||||
field: 'existingIndexPatternId',
|
||||
name: 'New index pattern',
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.flyout.renderConflicts.columnNewIndexPatternName',
|
||||
defaultMessage: 'New index pattern',
|
||||
}),
|
||||
render: id => {
|
||||
const options = this.state.indexPatterns.map(indexPattern => ({
|
||||
text: indexPattern.get('title'),
|
||||
|
@ -374,7 +419,9 @@ export class Flyout extends Component {
|
|||
return (
|
||||
<Fragment>
|
||||
<EuiCallOut
|
||||
title="Sorry, there was an error"
|
||||
title={(
|
||||
<FormattedMessage id="kbn.management.objects.objectsTable.flyout.errorCalloutTitle" defaultMessage="Sorry, there was an error"/>
|
||||
)}
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
>
|
||||
|
@ -412,12 +459,18 @@ export class Flyout extends Component {
|
|||
if (failedImports.length && !this.hasConflicts) {
|
||||
return (
|
||||
<EuiCallOut
|
||||
title="Import failed"
|
||||
title={(
|
||||
<FormattedMessage id="kbn.management.objects.objectsTable.flyout.importFailedTitle" defaultMessage="Import failed"/>
|
||||
)}
|
||||
color="warning"
|
||||
iconType="help"
|
||||
>
|
||||
<p>
|
||||
Failed to import {failedImports.length} of {importCount + failedImports.length} objects.
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.importFailedDescription"
|
||||
defaultMessage="Failed to import {failedImportCount} of {totalImportCount} objects.Import failed"
|
||||
values={{ failedImportCount: failedImports.length, totalImportCount: importCount + failedImports.length, }}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
{failedImports.map(({ error }) => getField(error, 'body.message', error.message || '')).join(' ')}
|
||||
|
@ -431,7 +484,12 @@ export class Flyout extends Component {
|
|||
return (
|
||||
<EuiCallOut
|
||||
data-test-subj="importSavedObjectsSuccessNoneImported"
|
||||
title="No objects imported"
|
||||
title={(
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.importSuccessfulCallout.noObjectsImportedTitle"
|
||||
defaultMessage="No objects imported"
|
||||
/>
|
||||
)}
|
||||
color="primary"
|
||||
/>
|
||||
);
|
||||
|
@ -440,11 +498,22 @@ export class Flyout extends Component {
|
|||
return (
|
||||
<EuiCallOut
|
||||
data-test-subj="importSavedObjectsSuccess"
|
||||
title="Import successful"
|
||||
title={(
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.importSuccessfulTitle"
|
||||
defaultMessage="Import successful"
|
||||
/>
|
||||
)}
|
||||
color="success"
|
||||
iconType="check"
|
||||
>
|
||||
<p>Successfully imported {importCount} objects.</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.importSuccessfulDescription"
|
||||
defaultMessage="Successfully imported {importCount} objects."
|
||||
values={{ importCount }}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
);
|
||||
}
|
||||
|
@ -455,16 +524,33 @@ export class Flyout extends Component {
|
|||
|
||||
return (
|
||||
<EuiForm>
|
||||
<EuiFormRow label="Please select a JSON file to import">
|
||||
<EuiFormRow
|
||||
label={(
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.selectFileToImportFormRowLabel"
|
||||
defaultMessage="Please select a JSON file to import"
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<EuiFilePicker
|
||||
initialPromptText="Import"
|
||||
initialPromptText={(
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.importPromptText"
|
||||
defaultMessage="Import"
|
||||
/>
|
||||
)}
|
||||
onChange={this.setImportFile}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow>
|
||||
<EuiSwitch
|
||||
name="overwriteAll"
|
||||
label="Automatically overwrite all saved objects?"
|
||||
label={(
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.overwriteSavedObjectsLabel"
|
||||
defaultMessage="Automatically overwrite all saved objects?"
|
||||
/>
|
||||
)}
|
||||
data-test-subj="importSavedObjectsOverwriteToggle"
|
||||
checked={isOverwriteAllChecked}
|
||||
onChange={this.changeOverwriteAll}
|
||||
|
@ -488,7 +574,10 @@ export class Flyout extends Component {
|
|||
fill
|
||||
data-test-subj="importSavedObjectsDoneBtn"
|
||||
>
|
||||
Done
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.importSuccessful.confirmButtonLabel"
|
||||
defaultMessage="Done"
|
||||
/>
|
||||
</EuiButton>
|
||||
);
|
||||
} else if (this.hasConflicts) {
|
||||
|
@ -500,7 +589,10 @@ export class Flyout extends Component {
|
|||
isLoading={isLoading}
|
||||
data-test-subj="importSavedObjectsConfirmBtn"
|
||||
>
|
||||
Confirm all changes
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.importSuccessful.confirmAllChangesButtonLabel"
|
||||
defaultMessage="Confirm all changes"
|
||||
/>
|
||||
</EuiButton>
|
||||
);
|
||||
} else {
|
||||
|
@ -512,7 +604,10 @@ export class Flyout extends Component {
|
|||
isLoading={isLoading}
|
||||
data-test-subj="importSavedObjectsImportBtn"
|
||||
>
|
||||
Import
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.import.confirmButtonLabel"
|
||||
defaultMessage="Import"
|
||||
/>
|
||||
</EuiButton>
|
||||
);
|
||||
}
|
||||
|
@ -521,7 +616,10 @@ export class Flyout extends Component {
|
|||
<EuiFlexGroup justifyContent="spaceBetween">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty onClick={close} size="s">
|
||||
Cancel
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.import.cancelButtonLabel"
|
||||
defaultMessage="Cancel"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>{confirmButton}</EuiFlexItem>
|
||||
|
@ -542,20 +640,32 @@ export class Flyout extends Component {
|
|||
<Fragment>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiCallOut
|
||||
title="Index Pattern Conflicts"
|
||||
title={(
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsTitle"
|
||||
defaultMessage="Index Pattern Conflicts"
|
||||
/>
|
||||
)}
|
||||
color="warning"
|
||||
iconType="help"
|
||||
>
|
||||
<p>
|
||||
The following saved objects use index patterns that do not exist.
|
||||
Please select the index patterns you'd like re-associated with
|
||||
them. You can{' '}
|
||||
{
|
||||
<EuiLink href={this.props.newIndexPatternUrl}>
|
||||
create a new index pattern
|
||||
</EuiLink>
|
||||
}{' '}
|
||||
if necessary.
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsDescription"
|
||||
defaultMessage="The following saved objects use index patterns that do not exist.
|
||||
Please select the index patterns you'd like re-associated with
|
||||
them. You can {indexPatternLink} if necessary."
|
||||
values={{
|
||||
indexPatternLink: (
|
||||
<EuiLink href={this.props.newIndexPatternUrl}>
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsCalloutLinkText"
|
||||
defaultMessage="create a new index pattern"
|
||||
/>
|
||||
</EuiLink>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</Fragment>
|
||||
|
@ -569,7 +679,12 @@ export class Flyout extends Component {
|
|||
<EuiFlyout onClose={close} size="s">
|
||||
<EuiFlyoutHeader>
|
||||
<EuiTitle>
|
||||
<h2>Import saved objects</h2>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.flyout.importSavedObjectTitle"
|
||||
defaultMessage="Import saved objects"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
{this.renderSubheader()}
|
||||
</EuiFlyoutHeader>
|
||||
|
@ -584,3 +699,5 @@ export class Flyout extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const Flyout = injectI18n(FlyoutUI);
|
||||
|
|
|
@ -19,7 +19,11 @@ exports[`Header should render normally 1`] = `
|
|||
size="m"
|
||||
>
|
||||
<h1>
|
||||
Saved Objects
|
||||
<FormattedMessage
|
||||
defaultMessage="Saved Objects"
|
||||
id="kbn.management.objects.objectsTable.header.savedObjectsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
|
@ -49,10 +53,15 @@ exports[`Header should render normally 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Export
|
||||
2
|
||||
|
||||
objects
|
||||
<FormattedMessage
|
||||
defaultMessage="Export {filteredCount, plural, one{# object} other {# objects}}"
|
||||
id="kbn.management.objects.objectsTable.header.exportButtonLabel"
|
||||
values={
|
||||
Object {
|
||||
"filteredCount": 2,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -68,7 +77,11 @@ exports[`Header should render normally 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Import
|
||||
<FormattedMessage
|
||||
defaultMessage="Import"
|
||||
id="kbn.management.objects.objectsTable.header.importButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -83,7 +96,11 @@ exports[`Header should render normally 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Refresh
|
||||
<FormattedMessage
|
||||
defaultMessage="Refresh"
|
||||
id="kbn.management.objects.objectsTable.header.refreshButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -100,7 +117,11 @@ exports[`Header should render normally 1`] = `
|
|||
color="subdued"
|
||||
component="span"
|
||||
>
|
||||
From here you can delete saved objects, such as saved searches. You can also edit the raw data of saved objects. Typically objects are only modified via their associated application, which is probably what you should use instead of this screen.
|
||||
<FormattedMessage
|
||||
defaultMessage="From here you can delete saved objects, such as saved searches. You can also edit the raw data of saved objects. Typically objects are only modified via their associated application, which is probably what you should use instead of this screen."
|
||||
id="kbn.management.objects.objectsTable.howToDeleteSavedObjectsDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiTextColor>
|
||||
</p>
|
||||
</EuiText>
|
||||
|
|
|
@ -29,6 +29,7 @@ import {
|
|||
EuiTextColor,
|
||||
EuiButtonEmpty,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export const Header = ({
|
||||
onExportAll,
|
||||
|
@ -40,7 +41,12 @@ export const Header = ({
|
|||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="baseline">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle>
|
||||
<h1>Saved Objects</h1>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.header.savedObjectsTitle"
|
||||
defaultMessage="Saved Objects"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
|
||||
|
@ -53,7 +59,13 @@ export const Header = ({
|
|||
data-test-subj="exportAllObjects"
|
||||
onClick={onExportAll}
|
||||
>
|
||||
Export {filteredCount} {filteredCount === 1 ? 'object' : 'objects'}
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.header.exportButtonLabel"
|
||||
defaultMessage="Export {filteredCount, plural, one{# object} other {# objects}}"
|
||||
values={{
|
||||
filteredCount
|
||||
}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -63,7 +75,10 @@ export const Header = ({
|
|||
data-test-subj="importObjects"
|
||||
onClick={onImport}
|
||||
>
|
||||
Import
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.header.importButtonLabel"
|
||||
defaultMessage="Import"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -72,7 +87,10 @@ export const Header = ({
|
|||
iconType="refresh"
|
||||
onClick={onRefresh}
|
||||
>
|
||||
Refresh
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.header.refreshButtonLabel"
|
||||
defaultMessage="Refresh"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -82,10 +100,13 @@ export const Header = ({
|
|||
<EuiText>
|
||||
<p>
|
||||
<EuiTextColor color="subdued">
|
||||
From here you can delete saved objects, such as saved searches.
|
||||
You can also edit the raw data of saved objects.
|
||||
Typically objects are only modified via their associated application,
|
||||
which is probably what you should use instead of this screen.
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.howToDeleteSavedObjectsDescription"
|
||||
defaultMessage="From here you can delete saved objects, such as saved searches.
|
||||
You can also edit the raw data of saved objects.
|
||||
Typically objects are only modified via their associated application,
|
||||
which is probably what you should use instead of this screen."
|
||||
/>
|
||||
</EuiTextColor>
|
||||
</p>
|
||||
</EuiText>
|
||||
|
|
|
@ -52,12 +52,20 @@ exports[`Relationships should render dashboards normally 1`] = `
|
|||
<EuiCallOut
|
||||
color="success"
|
||||
size="m"
|
||||
title="Dashboard"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Dashboard"
|
||||
id="kbn.management.objects.objectsTable.relationships.dashboard.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Here are some visualizations used on this dashboard. You can
|
||||
safely delete this dashboard and the visualizations will still
|
||||
work properly.
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some visualizations used on this dashboard. You can safely delete this dashboard and the visualizations will still work properly."
|
||||
id="kbn.management.objects.objectsTable.relationships.dashboard.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
|
@ -142,7 +150,13 @@ exports[`Relationships should render errors 1`] = `
|
|||
<EuiCallOut
|
||||
color="danger"
|
||||
size="m"
|
||||
title="Error"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Error"
|
||||
id="kbn.management.objects.objectsTable.relationships.renderErrorMessage"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
foo
|
||||
</EuiCallOut>
|
||||
|
@ -242,10 +256,20 @@ exports[`Relationships should render searches normally 1`] = `
|
|||
<EuiCallOut
|
||||
color="success"
|
||||
size="m"
|
||||
title="Saved Search"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Saved Search"
|
||||
id="kbn.management.objects.objectsTable.relationships.search.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Here is the index pattern tied to this saved search.
|
||||
<FormattedMessage
|
||||
defaultMessage="Here is the index pattern tied to this saved search."
|
||||
id="kbn.management.objects.objectsTable.relationships.search.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
|
@ -299,12 +323,20 @@ exports[`Relationships should render searches normally 1`] = `
|
|||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title="Warning"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Warning"
|
||||
id="kbn.management.objects.objectsTable.relationships.warningTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Here are some visualizations that use this saved search. If
|
||||
you delete this saved search, these visualizations will not
|
||||
longer work properly.
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some visualizations that use this saved search. If you delete this saved search, these visualizations will not longer work properly."
|
||||
id="kbn.management.objects.objectsTable.relationships.search.visualizations.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
|
@ -402,12 +434,20 @@ exports[`Relationships should render visualizations normally 1`] = `
|
|||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title="Warning"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Warning"
|
||||
id="kbn.management.objects.objectsTable.relationships.warningTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Here are some dashboards which contain this visualization. If
|
||||
you delete this visualization, these dashboards will no longer
|
||||
show them.
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some dashboards which contain this visualization. If you delete this visualization, these dashboards will no longer show them."
|
||||
id="kbn.management.objects.objectsTable.relationships.visualization.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
jest.mock('ui/errors', () => ({
|
||||
SavedObjectNotFound: class SavedObjectNotFound extends Error {
|
||||
|
@ -62,8 +62,8 @@ describe('Relationships', () => {
|
|||
close: jest.fn(),
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<Relationships
|
||||
const component = shallowWithIntl(
|
||||
<Relationships.WrappedComponent
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
@ -102,8 +102,8 @@ describe('Relationships', () => {
|
|||
close: jest.fn(),
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<Relationships
|
||||
const component = shallowWithIntl(
|
||||
<Relationships.WrappedComponent
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
@ -140,8 +140,8 @@ describe('Relationships', () => {
|
|||
close: jest.fn(),
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<Relationships
|
||||
const component = shallowWithIntl(
|
||||
<Relationships.WrappedComponent
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
@ -178,8 +178,8 @@ describe('Relationships', () => {
|
|||
close: jest.fn(),
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<Relationships
|
||||
const component = shallowWithIntl(
|
||||
<Relationships.WrappedComponent
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
@ -209,8 +209,8 @@ describe('Relationships', () => {
|
|||
close: jest.fn(),
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<Relationships
|
||||
const component = shallowWithIntl(
|
||||
<Relationships.WrappedComponent
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -34,9 +34,10 @@ import {
|
|||
EuiInMemoryTable,
|
||||
EuiToolTip
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
import { getSavedObjectIcon, getSavedObjectLabel } from '../../../../lib';
|
||||
|
||||
export class Relationships extends Component {
|
||||
class RelationshipsUI extends Component {
|
||||
static propTypes = {
|
||||
getRelationships: PropTypes.func.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -88,14 +89,19 @@ export class Relationships extends Component {
|
|||
}
|
||||
|
||||
return (
|
||||
<EuiCallOut title="Error" color="danger">
|
||||
<EuiCallOut
|
||||
title={(
|
||||
<FormattedMessage id="kbn.management.objects.objectsTable.relationships.renderErrorMessage" defaultMessage="Error"/>
|
||||
)}
|
||||
color="danger"
|
||||
>
|
||||
{error}
|
||||
</EuiCallOut>
|
||||
);
|
||||
}
|
||||
|
||||
renderRelationships() {
|
||||
const { getEditUrl, goInApp } = this.props;
|
||||
const { getEditUrl, goInApp, intl } = this.props;
|
||||
const { relationships, isLoading, error } = this.state;
|
||||
|
||||
if (error) {
|
||||
|
@ -112,48 +118,78 @@ export class Relationships extends Component {
|
|||
if (list.length === 0) {
|
||||
items.push(
|
||||
<EuiDescriptionListTitle key={`${type}_not_found`}>
|
||||
No {type} found.
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.itemNotFoundText"
|
||||
defaultMessage="No {type} found."
|
||||
values={{ type }}
|
||||
/>
|
||||
</EuiDescriptionListTitle>
|
||||
);
|
||||
} else {
|
||||
// let node;
|
||||
let calloutTitle = 'Warning';
|
||||
let calloutTitle = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.warningTitle"
|
||||
defaultMessage="Warning"
|
||||
/>);
|
||||
let calloutColor = 'warning';
|
||||
let calloutText;
|
||||
|
||||
switch (this.props.type) {
|
||||
case 'dashboard':
|
||||
calloutColor = 'success';
|
||||
calloutTitle = 'Dashboard';
|
||||
calloutText = `Here are some visualizations used on this dashboard. You can
|
||||
safely delete this dashboard and the visualizations will still
|
||||
work properly.`;
|
||||
calloutTitle = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.dashboard.calloutTitle"
|
||||
defaultMessage="Dashboard"
|
||||
/>);
|
||||
calloutText = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.dashboard.calloutText"
|
||||
defaultMessage="Here are some visualizations used on this dashboard.
|
||||
You can safely delete this dashboard and the visualizations will still work properly."
|
||||
/>);
|
||||
break;
|
||||
case 'search':
|
||||
if (type === 'visualizations') {
|
||||
calloutText = `Here are some visualizations that use this saved search. If
|
||||
you delete this saved search, these visualizations will not
|
||||
longer work properly.`;
|
||||
calloutText = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.search.visualizations.calloutText"
|
||||
defaultMessage="Here are some visualizations that use this saved search. If
|
||||
you delete this saved search, these visualizations will not
|
||||
longer work properly."
|
||||
/>);
|
||||
} else {
|
||||
calloutColor = 'success';
|
||||
calloutTitle = 'Saved Search';
|
||||
calloutText = `Here is the index pattern tied to this saved search.`;
|
||||
calloutTitle = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.search.calloutTitle"
|
||||
defaultMessage="Saved Search"
|
||||
/>);
|
||||
calloutText = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.search.calloutText"
|
||||
defaultMessage="Here is the index pattern tied to this saved search."
|
||||
/>);
|
||||
}
|
||||
break;
|
||||
case 'visualization':
|
||||
calloutText = `Here are some dashboards which contain this visualization. If
|
||||
you delete this visualization, these dashboards will no longer
|
||||
show them.`;
|
||||
calloutText = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.visualization.calloutText"
|
||||
defaultMessage="Here are some dashboards which contain this visualization. If
|
||||
you delete this visualization, these dashboards will no longer
|
||||
show them."
|
||||
/>);
|
||||
break;
|
||||
case 'index-pattern':
|
||||
if (type === 'visualizations') {
|
||||
calloutText = `Here are some visualizations that use this index pattern. If
|
||||
you delete this index pattern, these visualizations will not
|
||||
longer work properly.`;
|
||||
calloutText = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.indexPattern.visualizations.calloutText"
|
||||
defaultMessage="Here are some visualizations that use this index pattern. If
|
||||
you delete this index pattern, these visualizations will not
|
||||
longer work properly."
|
||||
/>);
|
||||
} else if (type === 'searches') {
|
||||
calloutText = `Here are some saved searches that use this index pattern. If
|
||||
you delete this index pattern, these saved searches will not
|
||||
longer work properly.`;
|
||||
calloutText = (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.relationships.indexPattern.searches.calloutText"
|
||||
defaultMessage="Here are some saved searches that use this index pattern. If
|
||||
you delete this index pattern, these saved searches will not
|
||||
longer work properly."
|
||||
/>);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -184,7 +220,9 @@ export class Relationships extends Component {
|
|||
),
|
||||
},
|
||||
{
|
||||
name: 'Title',
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.relationships.columnTitleName', defaultMessage: 'Title'
|
||||
}),
|
||||
field: 'title',
|
||||
render: (title, item) => (
|
||||
<EuiLink href={`${getEditUrl(item.id, type)}`}>
|
||||
|
@ -193,11 +231,19 @@ export class Relationships extends Component {
|
|||
),
|
||||
},
|
||||
{
|
||||
name: 'Actions',
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.relationships.columnActionsName', defaultMessage: 'Actions'
|
||||
}),
|
||||
actions: [
|
||||
{
|
||||
name: 'In app',
|
||||
description: 'View this saved object within Kibana',
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.relationships.columnActions.inAppName',
|
||||
defaultMessage: 'In app'
|
||||
}),
|
||||
description: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.relationships.columnActions.inAppDescription',
|
||||
defaultMessage: 'View this saved object within Kibana'
|
||||
}),
|
||||
icon: 'eye',
|
||||
onClick: object => goInApp(object.id, type),
|
||||
},
|
||||
|
@ -240,3 +286,5 @@ export class Relationships extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const Relationships = injectI18n(RelationshipsUI);
|
||||
|
|
|
@ -30,7 +30,11 @@ exports[`Table should render normally 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Delete
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete"
|
||||
id="kbn.management.objects.objectsTable.table.deleteButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>,
|
||||
<EuiButton
|
||||
color="primary"
|
||||
|
@ -41,7 +45,11 @@ exports[`Table should render normally 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Export
|
||||
<FormattedMessage
|
||||
defaultMessage="Export"
|
||||
id="kbn.management.objects.objectsTable.table.exportButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>,
|
||||
]
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
jest.mock('ui/errors', () => ({
|
||||
SavedObjectNotFound: class SavedObjectNotFound extends Error {
|
||||
|
@ -64,8 +64,8 @@ describe('Table', () => {
|
|||
onShowRelationships: () => {},
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<Table
|
||||
const component = shallowWithIntl(
|
||||
<Table.WrappedComponent
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -30,8 +30,9 @@ import {
|
|||
EuiToolTip
|
||||
} from '@elastic/eui';
|
||||
import { getSavedObjectLabel, getSavedObjectIcon } from '../../../../lib';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
export class Table extends PureComponent {
|
||||
class TableUI extends PureComponent {
|
||||
static propTypes = {
|
||||
selectedSavedObjects: PropTypes.array.isRequired,
|
||||
selectionConfig: PropTypes.shape({
|
||||
|
@ -78,6 +79,7 @@ export class Table extends PureComponent {
|
|||
goInApp,
|
||||
getEditUrl,
|
||||
onShowRelationships,
|
||||
intl,
|
||||
} = this.props;
|
||||
|
||||
const pagination = {
|
||||
|
@ -91,7 +93,7 @@ export class Table extends PureComponent {
|
|||
{
|
||||
type: 'field_value_selection',
|
||||
field: 'type',
|
||||
name: 'Type',
|
||||
name: intl.formatMessage({ id: 'kbn.management.objects.objectsTable.table.typeFilterName', defaultMessage: 'Type' }),
|
||||
multiSelect: 'or',
|
||||
options: filterOptions,
|
||||
},
|
||||
|
@ -108,10 +110,13 @@ export class Table extends PureComponent {
|
|||
const columns = [
|
||||
{
|
||||
field: 'type',
|
||||
name: 'Type',
|
||||
name: intl.formatMessage({ id: 'kbn.management.objects.objectsTable.table.columnTypeName', defaultMessage: 'Type' }),
|
||||
width: '50px',
|
||||
align: 'center',
|
||||
description: `Type of the saved object`,
|
||||
description:
|
||||
intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.table.columnTypeDescription', defaultMessage: 'Type of the saved object'
|
||||
}),
|
||||
sortable: false,
|
||||
render: type => {
|
||||
return (
|
||||
|
@ -130,8 +135,11 @@ export class Table extends PureComponent {
|
|||
},
|
||||
{
|
||||
field: 'title',
|
||||
name: 'Title',
|
||||
description: `Title of the saved object`,
|
||||
name: intl.formatMessage({ id: 'kbn.management.objects.objectsTable.table.columnTitleName', defaultMessage: 'Title' }),
|
||||
description:
|
||||
intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.table.columnTitleDescription', defaultMessage: 'Title of the saved object'
|
||||
}),
|
||||
dataType: 'string',
|
||||
sortable: false,
|
||||
render: (title, object) => (
|
||||
|
@ -139,20 +147,32 @@ export class Table extends PureComponent {
|
|||
),
|
||||
},
|
||||
{
|
||||
name: 'Actions',
|
||||
name: intl.formatMessage({ id: 'kbn.management.objects.objectsTable.table.columnActionsName', defaultMessage: 'Actions' }),
|
||||
actions: [
|
||||
{
|
||||
name: 'In app',
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.table.columnActions.viewInAppActionName', defaultMessage: 'In app'
|
||||
}),
|
||||
description:
|
||||
'View this saved object within Kibana',
|
||||
intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.table.columnActions.viewInAppActionDescription',
|
||||
defaultMessage: 'View this saved object within Kibana'
|
||||
}),
|
||||
type: 'icon',
|
||||
icon: 'eye',
|
||||
onClick: object => goInApp(object.id, object.type),
|
||||
},
|
||||
{
|
||||
name: 'Relationships',
|
||||
name:
|
||||
intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.table.columnActions.viewRelationshipsActionName',
|
||||
defaultMessage: 'Relationships'
|
||||
}),
|
||||
description:
|
||||
'View the relationships this saved object has to other saved objects',
|
||||
intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.table.columnActions.viewRelationshipsActionDescription',
|
||||
defaultMessage: 'View the relationships this saved object has to other saved objects'
|
||||
}),
|
||||
type: 'icon',
|
||||
icon: 'kqlSelector',
|
||||
onClick: object =>
|
||||
|
@ -175,7 +195,10 @@ export class Table extends PureComponent {
|
|||
onClick={onDelete}
|
||||
isDisabled={selectedSavedObjects.length === 0}
|
||||
>
|
||||
Delete
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.table.deleteButtonLabel"
|
||||
defaultMessage="Delete"
|
||||
/>
|
||||
</EuiButton>,
|
||||
<EuiButton
|
||||
key="exportSO"
|
||||
|
@ -183,7 +206,10 @@ export class Table extends PureComponent {
|
|||
onClick={onExport}
|
||||
isDisabled={selectedSavedObjects.length === 0}
|
||||
>
|
||||
Export
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.table.exportButtonLabel"
|
||||
defaultMessage="Export"
|
||||
/>
|
||||
</EuiButton>,
|
||||
]}
|
||||
/>
|
||||
|
@ -203,3 +229,5 @@ export class Table extends PureComponent {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const Table = injectI18n(TableUI);
|
||||
|
|
|
@ -51,6 +51,7 @@ import {
|
|||
getSavedObjectLabel,
|
||||
} from '../../lib';
|
||||
import { ensureMinimumTime } from '../../../indices/create_index_pattern_wizard/lib/ensure_minimum_time';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
export const INCLUDED_TYPES = [
|
||||
'index-pattern',
|
||||
|
@ -59,7 +60,7 @@ export const INCLUDED_TYPES = [
|
|||
'search',
|
||||
];
|
||||
|
||||
export class ObjectsTable extends Component {
|
||||
class ObjectsTableUI extends Component {
|
||||
static propTypes = {
|
||||
savedObjectsClient: PropTypes.object.isRequired,
|
||||
indexPatterns: PropTypes.object.isRequired,
|
||||
|
@ -383,6 +384,7 @@ export class ObjectsTable extends Component {
|
|||
isDeleting,
|
||||
selectedSavedObjects,
|
||||
} = this.state;
|
||||
const { intl } = this.props;
|
||||
|
||||
if (!isShowingDeleteConfirmModal) {
|
||||
return null;
|
||||
|
@ -406,20 +408,47 @@ export class ObjectsTable extends Component {
|
|||
|
||||
modal = (
|
||||
<EuiConfirmModal
|
||||
title="Delete saved objects"
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModalTitle"
|
||||
defaultMessage="Delete saved objects"
|
||||
/>
|
||||
}
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText={isDeleting ? 'Deleting...' : 'Delete'}
|
||||
cancelButtonText={(
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModal.cancelButtonLabel"
|
||||
defaultMessage="Cancel"
|
||||
/>
|
||||
)}
|
||||
confirmButtonText={
|
||||
isDeleting
|
||||
? (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModal.deleteProcessButtonLabel"
|
||||
defaultMessage="Deleting…"
|
||||
/>)
|
||||
: (<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModal.deleteButtonLabel"
|
||||
defaultMessage="Delete"
|
||||
/>)
|
||||
}
|
||||
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
|
||||
>
|
||||
<p>This action will delete the following saved objects:</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.deleteSavedObjectsConfirmModalDescription"
|
||||
defaultMessage="This action will delete the following saved objects:"
|
||||
/>
|
||||
</p>
|
||||
<EuiInMemoryTable
|
||||
items={selectedSavedObjects}
|
||||
columns={[
|
||||
{
|
||||
field: 'type',
|
||||
name: 'Type',
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModal.typeColumnName', defaultMessage: 'Type'
|
||||
}),
|
||||
width: '50px',
|
||||
render: type => (
|
||||
<EuiToolTip
|
||||
|
@ -432,7 +461,9 @@ export class ObjectsTable extends Component {
|
|||
},
|
||||
{
|
||||
field: 'id',
|
||||
name: 'Id/Name',
|
||||
name: intl.formatMessage({
|
||||
id: 'kbn.management.objects.objectsTable.deleteSavedObjectsConfirmModal.idColumnName', defaultMessage: 'Id/Name'
|
||||
}),
|
||||
},
|
||||
]}
|
||||
pagination={true}
|
||||
|
@ -464,18 +495,34 @@ export class ObjectsTable extends Component {
|
|||
return (
|
||||
<EuiOverlayMask>
|
||||
<EuiConfirmModal
|
||||
title={`Export ${filteredItemCount} ${filteredItemCount === 1 ? 'object' : 'objects'}`}
|
||||
title={(<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.exportObjectsConfirmModalTitle"
|
||||
defaultMessage="Export {filteredItemCount, plural, one{# object} other {# objects}}"
|
||||
values={{
|
||||
filteredItemCount
|
||||
}}
|
||||
/>)}
|
||||
onCancel={() =>
|
||||
this.setState({ isShowingExportAllOptionsModal: false })
|
||||
}
|
||||
onConfirm={this.onExportAll}
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Export All"
|
||||
cancelButtonText={(
|
||||
<FormattedMessage id="kbn.management.objects.objectsTable.exportObjectsConfirmModal.cancelButtonLabel" defaultMessage="Cancel"/>
|
||||
)}
|
||||
confirmButtonText={(
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.exportObjectsConfirmModal.exportAllButtonLabel"
|
||||
defaultMessage="Export All"
|
||||
/>
|
||||
)}
|
||||
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
|
||||
>
|
||||
<p>
|
||||
Select which types to export. The number in parentheses indicates
|
||||
how many of this type are available to export.
|
||||
<FormattedMessage
|
||||
id="kbn.management.objects.objectsTable.exportObjectsConfirmModalDescription"
|
||||
defaultMessage="Select which types to export. The number in parentheses indicates
|
||||
how many of this type are available to export."
|
||||
/>
|
||||
</p>
|
||||
<EuiCheckboxGroup
|
||||
options={exportAllOptions}
|
||||
|
@ -522,7 +569,11 @@ export class ObjectsTable extends Component {
|
|||
return (
|
||||
<EuiPage>
|
||||
<EuiPageBody>
|
||||
<EuiPageContent verticalPosition="center" horizontalPosition="center" style={{ maxWidth: 1000, marginTop: 16, marginBottom: 16 }}>
|
||||
<EuiPageContent
|
||||
verticalPosition="center"
|
||||
horizontalPosition="center"
|
||||
style={{ maxWidth: 1000, marginTop: 16, marginBottom: 16 }}
|
||||
>
|
||||
{this.renderFlyout()}
|
||||
{this.renderRelationships()}
|
||||
{this.renderDeleteConfirmModal()}
|
||||
|
@ -560,3 +611,5 @@ export class ObjectsTable extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const ObjectsTable = injectI18n(ObjectsTableUI);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { management } from 'ui/management';
|
||||
import './_view';
|
||||
import './_objects';
|
||||
|
@ -29,7 +30,9 @@ import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/r
|
|||
uiModules.get('apps/management');
|
||||
|
||||
management.getSection('kibana').register('objects', {
|
||||
display: 'Saved Objects',
|
||||
display: i18n.translate('kbn.management.objects.savedObjectsSectionLabel', {
|
||||
defaultMessage: 'Saved Objects',
|
||||
}),
|
||||
order: 10,
|
||||
url: '#/management/kibana/objects'
|
||||
});
|
||||
|
@ -37,8 +40,12 @@ management.getSection('kibana').register('objects', {
|
|||
FeatureCatalogueRegistryProvider.register(() => {
|
||||
return {
|
||||
id: 'saved_objects',
|
||||
title: 'Saved Objects',
|
||||
description: 'Import, export, and manage your saved searches, visualizations, and dashboards.',
|
||||
title: i18n.translate('kbn.management.objects.savedObjectsTitle', {
|
||||
defaultMessage: 'Saved Objects',
|
||||
}),
|
||||
description: i18n.translate('kbn.management.objects.savedObjectsDescription', {
|
||||
defaultMessage: 'Import, export, and manage your saved searches, visualizations, and dashboards.',
|
||||
}),
|
||||
icon: 'savedObjectsApp',
|
||||
path: '/app/kibana#/management/kibana/objects',
|
||||
showOnHomePage: true,
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
import { SavedObjectNotFound } from 'ui/errors';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
async function getSavedObject(doc, services) {
|
||||
const service = services.find(service => service.type === doc._type);
|
||||
|
@ -36,7 +37,16 @@ function addJsonFieldToIndexPattern(target, sourceString, fieldName, indexName)
|
|||
try {
|
||||
target[fieldName] = JSON.parse(sourceString);
|
||||
} catch (error) {
|
||||
throw new Error(`Error encountered parsing ${fieldName} for index pattern ${indexName}: ${error.message}`);
|
||||
throw new Error(
|
||||
i18n.translate('kbn.management.objects.parsingFieldErrorMessage', {
|
||||
defaultMessage: 'Error encountered parsing {fieldName} for index pattern {indexName}: {errorMessage}',
|
||||
values: {
|
||||
fieldName,
|
||||
indexName,
|
||||
errorMessage: error.message,
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue