Fix UI glitch on SOM delete confirmation modal (#87623)

* extract delete confirm modal

* extract the export modal

* add data-test-subj to confirm modal

* add comment on why we can't use EuiConfirmModal
This commit is contained in:
Pierre Gayvallet 2021-01-11 10:26:02 +01:00 committed by GitHub
parent 66c8b2a014
commit a0d33dc3a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 582 additions and 400 deletions

View file

@ -1,200 +1,62 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SavedObjectsTable delete should show a confirm modal 1`] = `
<EuiConfirmModal
buttonColor="danger"
cancelButtonText={
<FormattedMessage
defaultMessage="Cancel"
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.cancelButtonLabel"
values={Object {}}
/>
}
confirmButtonText={
<FormattedMessage
defaultMessage="Delete"
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.deleteButtonLabel"
values={Object {}}
/>
}
defaultFocusedButton="confirm"
<DeleteConfirmModal
isDeleting={false}
onCancel={[Function]}
onConfirm={[Function]}
title={
<FormattedMessage
defaultMessage="Delete saved objects"
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModalTitle"
values={Object {}}
/>
selectedObjects={
Array [
Object {
"id": "1",
"type": "index-pattern",
},
Object {
"id": "3",
"type": "dashboard",
},
]
}
>
<p>
<FormattedMessage
defaultMessage="This action will delete the following saved objects:"
id="savedObjectsManagement.deleteSavedObjectsConfirmModalDescription"
values={Object {}}
/>
</p>
<EuiInMemoryTable
columns={
Array [
Object {
"field": "type",
"name": "Type",
"render": [Function],
"width": "50px",
},
Object {
"field": "id",
"name": "Id",
},
Object {
"field": "meta.title",
"name": "Title",
},
]
}
items={
Array [
Object {
"id": "1",
"type": "index-pattern",
},
Object {
"id": "3",
"type": "dashboard",
},
]
}
pagination={true}
responsive={true}
sorting={false}
tableLayout="fixed"
/>
</EuiConfirmModal>
/>
`;
exports[`SavedObjectsTable export should allow the user to choose when exporting all 1`] = `
<EuiModal
onClose={[Function]}
>
<EuiModalHeader>
<EuiModalHeaderTitle>
<FormattedMessage
defaultMessage="Export {filteredItemCount, plural, one{# object} other {# objects}}"
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModalTitle"
values={
Object {
"filteredItemCount": 4,
}
}
/>
</EuiModalHeaderTitle>
</EuiModalHeader>
<EuiModalBody>
<EuiFormRow
describedByIds={Array []}
display="row"
fullWidth={false}
hasChildLabel={true}
hasEmptyLabelSpace={false}
label={
<FormattedMessage
defaultMessage="Select which types to export"
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModalDescription"
values={Object {}}
/>
}
labelType="legend"
>
<EuiCheckboxGroup
idToSelectedMap={
Object {
"dashboard": true,
"index-pattern": true,
"search": true,
"visualization": true,
}
}
onChange={[Function]}
options={
Array [
Object {
"id": "index-pattern",
"label": "index-pattern (0)",
},
Object {
"id": "visualization",
"label": "visualization (0)",
},
Object {
"id": "dashboard",
"label": "dashboard (0)",
},
Object {
"id": "search",
"label": "search (0)",
},
]
}
/>
</EuiFormRow>
<EuiSpacer
size="m"
/>
<EuiSwitch
checked={true}
label={
<FormattedMessage
defaultMessage="Include related objects"
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.includeReferencesDeepLabel"
values={Object {}}
/>
}
name="includeReferencesDeep"
onChange={[Function]}
/>
</EuiModalBody>
<EuiModalFooter>
<EuiFlexGroup
justifyContent="flexEnd"
>
<EuiFlexItem
grow={false}
>
<EuiFlexGroup>
<EuiFlexItem
grow={false}
>
<EuiButtonEmpty
onClick={[Function]}
>
<FormattedMessage
defaultMessage="Cancel"
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.cancelButtonLabel"
values={Object {}}
/>
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem
grow={false}
>
<EuiButton
fill={true}
onClick={[Function]}
>
<FormattedMessage
defaultMessage="Export all"
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.exportAllButtonLabel"
values={Object {}}
/>
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiModalFooter>
</EuiModal>
<ExportModal
filteredItemCount={4}
includeReferences={true}
onCancel={[Function]}
onExport={[Function]}
onIncludeReferenceChange={[Function]}
onSelectedOptionsChange={[Function]}
options={
Array [
Object {
"id": "index-pattern",
"label": "index-pattern (0)",
},
Object {
"id": "visualization",
"label": "visualization (0)",
},
Object {
"id": "dashboard",
"label": "dashboard (0)",
},
Object {
"id": "search",
"label": "search (0)",
},
]
}
selectedOptions={
Object {
"dashboard": true,
"index-pattern": true,
"search": true,
"visualization": true,
}
}
/>
`;
exports[`SavedObjectsTable should render normally 1`] = `

View file

@ -0,0 +1,97 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { mountWithIntl } from '@kbn/test/jest';
import { SavedObjectWithMetadata } from '../../../../common';
import { DeleteConfirmModal } from './delete_confirm_modal';
const createObject = (): SavedObjectWithMetadata => ({
id: 'foo',
type: 'bar',
attributes: {},
references: [],
meta: {},
});
describe('DeleteConfirmModal', () => {
let onConfirm: jest.Mock;
let onCancel: jest.Mock;
beforeEach(() => {
onConfirm = jest.fn();
onCancel = jest.fn();
});
it('displays a loader if `isDeleting` is true', () => {
const wrapper = mountWithIntl(
<DeleteConfirmModal
isDeleting={true}
onConfirm={onConfirm}
onCancel={onCancel}
selectedObjects={[]}
/>
);
expect(wrapper.find('EuiLoadingElastic')).toHaveLength(1);
expect(wrapper.find('EuiModal')).toHaveLength(0);
});
it('lists the objects to delete', () => {
const objs = [createObject(), createObject(), createObject()];
const wrapper = mountWithIntl(
<DeleteConfirmModal
isDeleting={false}
onConfirm={onConfirm}
onCancel={onCancel}
selectedObjects={objs}
/>
);
expect(wrapper.find('.euiTableRow')).toHaveLength(3);
});
it('calls `onCancel` when clicking on the cancel button', () => {
const wrapper = mountWithIntl(
<DeleteConfirmModal
isDeleting={false}
onConfirm={onConfirm}
onCancel={onCancel}
selectedObjects={[]}
/>
);
wrapper.find('EuiButtonEmpty').simulate('click');
expect(onCancel).toHaveBeenCalledTimes(1);
expect(onConfirm).not.toHaveBeenCalled();
});
it('calls `onDelete` when clicking on the delete button', () => {
const wrapper = mountWithIntl(
<DeleteConfirmModal
isDeleting={false}
onConfirm={onConfirm}
onCancel={onCancel}
selectedObjects={[]}
/>
);
wrapper.find('EuiButton').simulate('click');
expect(onConfirm).toHaveBeenCalledTimes(1);
expect(onCancel).not.toHaveBeenCalled();
});
});

View file

@ -0,0 +1,153 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { FC } from 'react';
import {
EuiInMemoryTable,
EuiLoadingElastic,
EuiToolTip,
EuiIcon,
EuiOverlayMask,
EuiModal,
EuiModalHeader,
EuiModalHeaderTitle,
EuiModalBody,
EuiModalFooter,
EuiFlexGroup,
EuiFlexItem,
EuiButtonEmpty,
EuiButton,
EuiSpacer,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { SavedObjectWithMetadata } from '../../../../common';
import { getSavedObjectLabel } from '../../../lib';
export interface DeleteConfirmModalProps {
isDeleting: boolean;
onConfirm: () => void;
onCancel: () => void;
selectedObjects: SavedObjectWithMetadata[];
}
export const DeleteConfirmModal: FC<DeleteConfirmModalProps> = ({
isDeleting,
onConfirm,
onCancel,
selectedObjects,
}) => {
if (isDeleting) {
return (
<EuiOverlayMask>
<EuiLoadingElastic size="xl" />
</EuiOverlayMask>
);
}
// can't use `EuiConfirmModal` here as the confirm modal body is wrapped
// inside a `<p>` element, causing UI glitches with the table.
return (
<EuiOverlayMask>
<EuiModal initialFocus="soDeleteConfirmModalConfirmBtn" onClose={onCancel}>
<EuiModalHeader>
<EuiModalHeaderTitle>
<FormattedMessage
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModalTitle"
defaultMessage="Delete saved objects"
/>
</EuiModalHeaderTitle>
</EuiModalHeader>
<EuiModalBody>
<p>
<FormattedMessage
id="savedObjectsManagement.deleteSavedObjectsConfirmModalDescription"
defaultMessage="This action will delete the following saved objects:"
/>
</p>
<EuiSpacer size="m" />
<EuiInMemoryTable
items={selectedObjects}
columns={[
{
field: 'type',
name: i18n.translate(
'savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.typeColumnName',
{ defaultMessage: 'Type' }
),
width: '50px',
render: (type, object) => (
<EuiToolTip position="top" content={getSavedObjectLabel(type)}>
<EuiIcon type={object.meta.icon || 'apps'} />
</EuiToolTip>
),
},
{
field: 'id',
name: i18n.translate(
'savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.idColumnName',
{ defaultMessage: 'Id' }
),
},
{
field: 'meta.title',
name: i18n.translate(
'savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.titleColumnName',
{ defaultMessage: 'Title' }
),
},
]}
pagination={true}
sorting={false}
/>
</EuiModalBody>
<EuiModalFooter>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onCancel} data-test-subj="confirmModalCancelButton">
<FormattedMessage
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.cancelButtonLabel"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
id="soDeleteConfirmModalConfirmBtn"
fill
color="danger"
onClick={onConfirm}
data-test-subj="confirmModalConfirmButton"
>
<FormattedMessage
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.deleteButtonLabel"
defaultMessage="Delete"
/>
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiModalFooter>
</EuiModal>
</EuiOverlayMask>
);
};

View file

@ -0,0 +1,100 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { mountWithIntl } from '@kbn/test/jest';
import { ExportModal } from './export_modal';
describe('ExportModal', () => {
let onExport: jest.Mock;
let onCancel: jest.Mock;
let onSelectedOptionsChange: jest.Mock;
let onIncludeReferenceChange: jest.Mock;
const options = [
{ id: '1', label: 'option 1' },
{ id: '2', label: 'option 2' },
];
const selectedOptions = {
1: true,
2: false,
};
beforeEach(() => {
onExport = jest.fn();
onCancel = jest.fn();
onSelectedOptionsChange = jest.fn();
onIncludeReferenceChange = jest.fn();
});
it('Displays a checkbox for each option', () => {
const wrapper = mountWithIntl(
<ExportModal
onExport={onExport}
onCancel={onCancel}
onSelectedOptionsChange={onSelectedOptionsChange}
filteredItemCount={42}
options={options}
selectedOptions={selectedOptions}
includeReferences={false}
onIncludeReferenceChange={onIncludeReferenceChange}
/>
);
expect(wrapper.find('EuiCheckbox')).toHaveLength(2);
});
it('calls `onCancel` when clicking on the cancel button', () => {
const wrapper = mountWithIntl(
<ExportModal
onExport={onExport}
onCancel={onCancel}
onSelectedOptionsChange={onSelectedOptionsChange}
filteredItemCount={42}
options={options}
selectedOptions={selectedOptions}
includeReferences={false}
onIncludeReferenceChange={onIncludeReferenceChange}
/>
);
wrapper.find('EuiButtonEmpty').simulate('click');
expect(onCancel).toHaveBeenCalledTimes(1);
expect(onExport).not.toHaveBeenCalled();
});
it('calls `onExport` when clicking on the export button', () => {
const wrapper = mountWithIntl(
<ExportModal
onExport={onExport}
onCancel={onCancel}
onSelectedOptionsChange={onSelectedOptionsChange}
filteredItemCount={42}
options={options}
selectedOptions={selectedOptions}
includeReferences={false}
onIncludeReferenceChange={onIncludeReferenceChange}
/>
);
wrapper.find('EuiButton').simulate('click');
expect(onExport).toHaveBeenCalledTimes(1);
expect(onCancel).not.toHaveBeenCalled();
});
});

View file

@ -0,0 +1,137 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { FC } from 'react';
import {
EuiOverlayMask,
EuiModal,
EuiModalHeader,
EuiModalHeaderTitle,
EuiModalBody,
EuiModalFooter,
EuiFlexGroup,
EuiFlexItem,
EuiButtonEmpty,
EuiButton,
EuiSpacer,
EuiFormRow,
EuiCheckboxGroup,
EuiSwitch,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
export interface ExportModalProps {
onExport: () => void;
onCancel: () => void;
onSelectedOptionsChange: (newSelectedOptions: Record<string, boolean>) => void;
filteredItemCount: number;
options: Array<{ id: string; label: string }>;
selectedOptions: Record<string, boolean>;
includeReferences: boolean;
onIncludeReferenceChange: (newIncludeReference: boolean) => void;
}
export const ExportModal: FC<ExportModalProps> = ({
onCancel,
onExport,
onSelectedOptionsChange,
options,
filteredItemCount,
selectedOptions,
includeReferences,
onIncludeReferenceChange,
}) => {
return (
<EuiOverlayMask>
<EuiModal onClose={onCancel}>
<EuiModalHeader>
<EuiModalHeaderTitle>
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModalTitle"
defaultMessage="Export {filteredItemCount, plural, one{# object} other {# objects}}"
values={{
filteredItemCount,
}}
/>
</EuiModalHeaderTitle>
</EuiModalHeader>
<EuiModalBody>
<EuiFormRow
label={
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModalDescription"
defaultMessage="Select which types to export"
/>
}
labelType="legend"
>
<EuiCheckboxGroup
options={options}
idToSelectedMap={selectedOptions}
onChange={(optionId) => {
onSelectedOptionsChange({
...selectedOptions,
...{
[optionId]: !selectedOptions[optionId],
},
});
}}
/>
</EuiFormRow>
<EuiSpacer size="m" />
<EuiSwitch
name="includeReferencesDeep"
label={
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.includeReferencesDeepLabel"
defaultMessage="Include related objects"
/>
}
checked={includeReferences}
onChange={() => onIncludeReferenceChange(!includeReferences)}
/>
</EuiModalBody>
<EuiModalFooter>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onCancel}>
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.cancelButtonLabel"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton fill onClick={onExport}>
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.exportAllButtonLabel"
defaultMessage="Export all"
/>
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiModalFooter>
</EuiModal>
</EuiOverlayMask>
);
};

View file

@ -21,3 +21,5 @@ export { Header } from './header';
export { Table } from './table';
export { Flyout } from './flyout';
export { Relationships } from './relationships';
export { DeleteConfirmModal } from './delete_confirm_modal';
export { ExportModal } from './export_modal';

View file

@ -325,7 +325,7 @@ describe('SavedObjectsTable', () => {
(component.find('Header') as any).prop('onExportAll')();
component.update();
expect(component.find('EuiModal')).toMatchSnapshot();
expect(component.find('ExportModal')).toMatchSnapshot();
});
it('should export all', async () => {
@ -504,7 +504,7 @@ describe('SavedObjectsTable', () => {
await component.instance().onDelete();
component.update();
expect(component.find('EuiConfirmModal')).toMatchSnapshot();
expect(component.find('DeleteConfirmModal')).toMatchSnapshot();
});
it('should delete selected objects', async () => {

View file

@ -21,32 +21,8 @@ import React, { Component } from 'react';
import { debounce } from 'lodash';
// @ts-expect-error
import { saveAs } from '@elastic/filesaver';
import {
EuiSpacer,
Query,
EuiInMemoryTable,
EuiIcon,
EuiConfirmModal,
EuiLoadingElastic,
EuiOverlayMask,
EUI_MODAL_CONFIRM_BUTTON,
EuiCheckboxGroup,
EuiToolTip,
EuiPageContent,
EuiSwitch,
EuiModal,
EuiModalHeader,
EuiModalBody,
EuiModalFooter,
EuiButtonEmpty,
EuiButton,
EuiModalHeaderTitle,
EuiFormRow,
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
import { EuiSpacer, Query, EuiPageContent } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import {
SavedObjectsClientContract,
SavedObjectsFindOptions,
@ -62,7 +38,6 @@ import {
parseQuery,
getSavedObjectCounts,
getRelationships,
getSavedObjectLabel,
fetchExportObjects,
fetchExportByTypeAndSearch,
findObjects,
@ -77,7 +52,14 @@ import {
SavedObjectsManagementActionServiceStart,
SavedObjectsManagementColumnServiceStart,
} from '../../services';
import { Header, Table, Flyout, Relationships } from './components';
import {
Header,
Table,
Flyout,
Relationships,
DeleteConfirmModal,
ExportModal,
} from './components';
import { DataPublicPluginStart } from '../../../../../plugins/data/public';
interface ExportAllOption {
@ -554,114 +536,24 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb
renderDeleteConfirmModal() {
const { isShowingDeleteConfirmModal, isDeleting, selectedSavedObjects } = this.state;
if (!isShowingDeleteConfirmModal) {
return null;
}
let modal;
if (isDeleting) {
// Block the user from interacting with the table while its contents are being deleted.
modal = <EuiLoadingElastic size="xl" />;
} else {
const onCancel = () => {
this.setState({ isShowingDeleteConfirmModal: false });
};
const onConfirm = () => {
this.delete();
};
modal = (
<EuiConfirmModal
title={
<FormattedMessage
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModalTitle"
defaultMessage="Delete saved objects"
/>
}
onCancel={onCancel}
onConfirm={onConfirm}
buttonColor="danger"
cancelButtonText={
<FormattedMessage
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.cancelButtonLabel"
defaultMessage="Cancel"
/>
}
confirmButtonText={
isDeleting ? (
<FormattedMessage
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.deleteProcessButtonLabel"
defaultMessage="Deleting…"
/>
) : (
<FormattedMessage
id="savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.deleteButtonLabel"
defaultMessage="Delete"
/>
)
}
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
>
<p>
<FormattedMessage
id="savedObjectsManagement.deleteSavedObjectsConfirmModalDescription"
defaultMessage="This action will delete the following saved objects:"
/>
</p>
<EuiInMemoryTable
items={selectedSavedObjects}
columns={[
{
field: 'type',
name: i18n.translate(
'savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.typeColumnName',
{ defaultMessage: 'Type' }
),
width: '50px',
render: (type, object) => (
<EuiToolTip position="top" content={getSavedObjectLabel(type)}>
<EuiIcon type={object.meta.icon || 'apps'} />
</EuiToolTip>
),
},
{
field: 'id',
name: i18n.translate(
'savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.idColumnName',
{ defaultMessage: 'Id' }
),
},
{
field: 'meta.title',
name: i18n.translate(
'savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.titleColumnName',
{ defaultMessage: 'Title' }
),
},
]}
pagination={true}
sorting={false}
/>
</EuiConfirmModal>
);
}
return <EuiOverlayMask>{modal}</EuiOverlayMask>;
return (
<DeleteConfirmModal
isDeleting={isDeleting}
onConfirm={() => {
this.delete();
}}
onCancel={() => {
this.setState({ isShowingDeleteConfirmModal: false });
}}
selectedObjects={selectedSavedObjects}
/>
);
}
changeIncludeReferencesDeep = () => {
this.setState((state) => ({
isIncludeReferencesDeepChecked: !state.isIncludeReferencesDeepChecked,
}));
};
closeExportAllModal = () => {
this.setState({ isShowingExportAllOptionsModal: false });
};
renderExportAllOptionsModal() {
const {
isShowingExportAllOptionsModal,
@ -676,85 +568,26 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb
}
return (
<EuiOverlayMask>
<EuiModal onClose={this.closeExportAllModal}>
<EuiModalHeader>
<EuiModalHeaderTitle>
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModalTitle"
defaultMessage="Export {filteredItemCount, plural, one{# object} other {# objects}}"
values={{
filteredItemCount,
}}
/>
</EuiModalHeaderTitle>
</EuiModalHeader>
<EuiModalBody>
<EuiFormRow
label={
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModalDescription"
defaultMessage="Select which types to export"
/>
}
labelType="legend"
>
<EuiCheckboxGroup
options={exportAllOptions}
idToSelectedMap={exportAllSelectedOptions}
onChange={(optionId) => {
const newExportAllSelectedOptions = {
...exportAllSelectedOptions,
...{
[optionId]: !exportAllSelectedOptions[optionId],
},
};
this.setState({
exportAllSelectedOptions: newExportAllSelectedOptions,
});
}}
/>
</EuiFormRow>
<EuiSpacer size="m" />
<EuiSwitch
name="includeReferencesDeep"
label={
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.includeReferencesDeepLabel"
defaultMessage="Include related objects"
/>
}
checked={isIncludeReferencesDeepChecked}
onChange={this.changeIncludeReferencesDeep}
/>
</EuiModalBody>
<EuiModalFooter>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={this.closeExportAllModal}>
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.cancelButtonLabel"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton fill onClick={this.onExportAll}>
<FormattedMessage
id="savedObjectsManagement.objectsTable.exportObjectsConfirmModal.exportAllButtonLabel"
defaultMessage="Export all"
/>
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiModalFooter>
</EuiModal>
</EuiOverlayMask>
<ExportModal
onExport={this.onExportAll}
onCancel={() => {
this.setState({ isShowingExportAllOptionsModal: false });
}}
onSelectedOptionsChange={(newOptions) => {
this.setState({
exportAllSelectedOptions: newOptions,
});
}}
filteredItemCount={filteredItemCount}
options={exportAllOptions}
selectedOptions={exportAllSelectedOptions}
includeReferences={isIncludeReferencesDeepChecked}
onIncludeReferenceChange={(newIncludeReferences) => {
this.setState({
isIncludeReferencesDeepChecked: newIncludeReferences,
});
}}
/>
);
}

View file

@ -3198,7 +3198,6 @@
"savedObjectsManagement.objects.savedObjectsTitle": "保存されたオブジェクト",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.cancelButtonLabel": "キャンセル",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.deleteButtonLabel": "削除",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.deleteProcessButtonLabel": "削除中…",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.idColumnName": "Id",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.titleColumnName": "タイトル",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.typeColumnName": "型",

View file

@ -3202,7 +3202,6 @@
"savedObjectsManagement.objects.savedObjectsTitle": "已保存对象",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.cancelButtonLabel": "取消",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.deleteButtonLabel": "删除",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.deleteProcessButtonLabel": "正在删除……",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.idColumnName": "ID",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.titleColumnName": "标题",
"savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.typeColumnName": "类型",