diff --git a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/__snapshots__/confirm_delete_modal.test.tsx.snap b/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/__snapshots__/confirm_delete_modal.test.tsx.snap
deleted file mode 100644
index 5bf93a1021c05..0000000000000
--- a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/__snapshots__/confirm_delete_modal.test.tsx.snap
+++ /dev/null
@@ -1,93 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`ConfirmDeleteModal renders as expected 1`] = `
-
-
-
-
-
-
-
-
-
-
-
- ,
- }
- }
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
diff --git a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.scss b/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.scss
deleted file mode 100644
index 887495a231485..0000000000000
--- a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.spcConfirmDeleteModal {
- max-width: $euiFormMaxWidth + ($euiSizeL * 2);
-}
diff --git a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.test.tsx b/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.test.tsx
index 36d282a1cd653..2fe85998fcfb2 100644
--- a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.test.tsx
+++ b/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.test.tsx
@@ -6,10 +6,10 @@
*/
import React from 'react';
+import { act } from 'react-dom/test-utils';
import { mountWithIntl, shallowWithIntl } from '@kbn/test/jest';
-import type { SpacesManager } from '../../../spaces_manager';
import { spacesManagerMock } from '../../../spaces_manager/mocks';
import { ConfirmDeleteModal } from './confirm_delete_modal';
@@ -22,25 +22,53 @@ describe('ConfirmDeleteModal', () => {
};
const spacesManager = spacesManagerMock.create();
- spacesManager.getActiveSpace.mockResolvedValue(space);
-
const onCancel = jest.fn();
- const onConfirm = jest.fn();
expect(
shallowWithIntl(
-
+
)
- ).toMatchSnapshot();
+ ).toMatchInlineSnapshot(`
+
+
+
+
+
+ ,
+ }
+ }
+ />
+
+
+
+
+
+
+ `);
});
- it(`requires the space name to be typed before confirming`, () => {
+ it('deletes the space when confirmed', async () => {
const space = {
id: 'my-space',
name: 'My Space',
@@ -48,34 +76,23 @@ describe('ConfirmDeleteModal', () => {
};
const spacesManager = spacesManagerMock.create();
- spacesManager.getActiveSpace.mockResolvedValue(space);
-
const onCancel = jest.fn();
- const onConfirm = jest.fn();
+ const onSuccess = jest.fn();
const wrapper = mountWithIntl(
-
);
- const input = wrapper.find('input');
- expect(input).toHaveLength(1);
-
- input.simulate('change', { target: { value: 'My Invalid Space Name ' } });
-
- const confirmButton = wrapper.find('button[data-test-subj="confirmModalConfirmButton"]');
- confirmButton.simulate('click');
-
- expect(onConfirm).not.toHaveBeenCalled();
-
- input.simulate('change', { target: { value: 'My Space' } });
- confirmButton.simulate('click');
+ await act(async () => {
+ wrapper.find('EuiButton[data-test-subj="confirmModalConfirmButton"]').simulate('click');
+ await spacesManager.deleteSpace.mock.results[0];
+ });
- expect(onConfirm).toHaveBeenCalledTimes(1);
+ expect(spacesManager.deleteSpace).toHaveBeenLastCalledWith(space);
});
});
diff --git a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.tsx b/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.tsx
index 100b5b6493e30..7cbe3ab7a71dc 100644
--- a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.tsx
+++ b/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/confirm_delete_modal.tsx
@@ -5,224 +5,127 @@
* 2.0.
*/
-import './confirm_delete_modal.scss';
-
-import type { CommonProps, EuiModalProps } from '@elastic/eui';
-import {
- EuiButton,
- EuiButtonEmpty,
- EuiCallOut,
- EuiFieldText,
- EuiFormRow,
- EuiModal,
- EuiModalBody,
- EuiModalFooter,
- EuiModalHeader,
- EuiModalHeaderTitle,
- EuiSpacer,
- EuiText,
-} from '@elastic/eui';
-import type { ChangeEvent } from 'react';
-import React, { Component } from 'react';
-
-import type { InjectedIntl } from '@kbn/i18n/react';
-import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
+import { EuiCallOut, EuiConfirmModal, EuiSpacer, EuiText } from '@elastic/eui';
+import type { FunctionComponent } from 'react';
+import React from 'react';
+import useAsync from 'react-use/lib/useAsync';
+import useAsyncFn from 'react-use/lib/useAsyncFn';
+
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import type { Space } from 'src/plugins/spaces_oss/common';
+import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import type { SpacesManager } from '../../../spaces_manager';
interface Props {
space: Space;
spacesManager: SpacesManager;
- onCancel: () => void;
- onConfirm: () => void;
- intl: InjectedIntl;
-}
-
-interface State {
- confirmSpaceName: string;
- error: boolean | null;
- deleteInProgress: boolean;
- isDeletingCurrentSpace: boolean;
+ onCancel(): void;
+ onSuccess?(): void;
}
-class ConfirmDeleteModalUI extends Component {
- public state = {
- confirmSpaceName: '',
- error: null,
- deleteInProgress: false,
- isDeletingCurrentSpace: false,
- };
-
- public componentDidMount() {
- isCurrentSpace(this.props.space, this.props.spacesManager).then((result) => {
- this.setState({
- isDeletingCurrentSpace: result,
- });
- });
- }
-
- public render() {
- const { space, onCancel, intl } = this.props;
- const { isDeletingCurrentSpace } = this.state;
-
- let warning = null;
- if (isDeletingCurrentSpace) {
- const name = (
-
- ({space.name})
-
- );
- warning = (
- <>
-
-
-
-
-
-
- >
+export const ConfirmDeleteModal: FunctionComponent = ({
+ space,
+ onSuccess,
+ onCancel,
+ spacesManager,
+}) => {
+ const { services } = useKibana();
+
+ const { value: isCurrentSpace } = useAsync(
+ async () => space.id === (await spacesManager.getActiveSpace()).id,
+ [space.id]
+ );
+
+ const [state, deleteSpace] = useAsyncFn(async () => {
+ try {
+ await spacesManager.deleteSpace(space);
+ services.notifications!.toasts.addSuccess(
+ i18n.translate('xpack.spaces.management.confirmDeleteModal.successMessage', {
+ defaultMessage: "Deleted space '{name}'",
+ values: { name: space.name },
+ })
);
- }
-
- // This is largely the same as the built-in EuiConfirmModal component, but we needed the ability
- // to disable the buttons since this could be a long-running operation
-
- const modalProps: Omit & CommonProps = {
- onClose: onCancel,
- className: 'spcConfirmDeleteModal',
- initialFocus: 'input[name="confirmDeleteSpaceInput"]',
- };
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- ),
- }}
- />
-
-
-
-
-
-
- {warning}
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-
- private onSpaceNameChange = (e: ChangeEvent) => {
- if (typeof this.state.error === 'boolean') {
- this.setState({
- confirmSpaceName: e.target.value,
- error: e.target.value !== this.props.space.name,
- });
- } else {
- this.setState({
- confirmSpaceName: e.target.value,
- });
- }
- };
-
- private onConfirm = async () => {
- if (this.state.confirmSpaceName === this.props.space.name) {
- const needsRedirect = this.state.isDeletingCurrentSpace;
- const spacesManager = this.props.spacesManager;
-
- this.setState({
- deleteInProgress: true,
- });
-
- await this.props.onConfirm();
-
- this.setState({
- deleteInProgress: false,
- });
-
- if (needsRedirect) {
+ if (isCurrentSpace) {
spacesManager.redirectToSpaceSelector();
+ } else {
+ onSuccess?.();
}
- } else {
- this.setState({
- error: true,
+ } catch (error) {
+ services.notifications!.toasts.addDanger({
+ title: i18n.translate('xpack.spaces.management.confirmDeleteModal.errorMessage', {
+ defaultMessage: "Could not delete space '{name}'",
+ values: { name: space.name },
+ }),
+ text: (error as any).body?.message || error.message,
});
}
- };
-}
-
-async function isCurrentSpace(space: Space, spacesManager: SpacesManager) {
- return space.id === (await spacesManager.getActiveSpace()).id;
-}
-
-export const ConfirmDeleteModal = injectI18n(ConfirmDeleteModalUI);
+ });
+
+ return (
+
+ {isCurrentSpace && (
+ <>
+
+
+
+
+ >
+ )}
+
+
+
+
+
+ ),
+ }}
+ />
+
+
+
+
+
+
+ );
+};
diff --git a/x-pack/plugins/spaces/public/management/edit_space/delete_spaces_button.tsx b/x-pack/plugins/spaces/public/management/edit_space/delete_spaces_button.tsx
index d03b878cb19ab..92b68426d172e 100644
--- a/x-pack/plugins/spaces/public/management/edit_space/delete_spaces_button.tsx
+++ b/x-pack/plugins/spaces/public/management/edit_space/delete_spaces_button.tsx
@@ -95,44 +95,13 @@ export class DeleteSpacesButton extends Component {
showConfirmDeleteModal: false,
});
}}
- onConfirm={this.deleteSpaces}
+ onSuccess={() => {
+ this.setState({
+ showConfirmDeleteModal: false,
+ });
+ this.props.onDelete?.();
+ }}
/>
);
};
-
- public deleteSpaces = async () => {
- const { spacesManager, space } = this.props;
-
- this.setState({
- showConfirmDeleteModal: false,
- });
-
- try {
- await spacesManager.deleteSpace(space);
- } catch (error) {
- const { message: errorMessage = '' } = error.data || error.body || {};
-
- this.props.notifications.toasts.addDanger(
- i18n.translate('xpack.spaces.management.deleteSpacesButton.deleteSpaceErrorTitle', {
- defaultMessage: 'Error deleting space: {errorMessage}',
- values: { errorMessage },
- })
- );
- return;
- }
-
- const message = i18n.translate(
- 'xpack.spaces.management.deleteSpacesButton.spaceSuccessfullyDeletedNotificationMessage',
- {
- defaultMessage: 'Deleted {spaceName} space.',
- values: { spaceName: space.name },
- }
- );
-
- this.props.notifications.toasts.addSuccess(message);
-
- if (this.props.onDelete) {
- this.props.onDelete();
- }
- };
}
diff --git a/x-pack/plugins/spaces/public/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap b/x-pack/plugins/spaces/public/management/spaces_grid/__snapshots__/spaces_grid_page.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/spaces/public/management/spaces_grid/__snapshots__/spaces_grid_pages.test.tsx.snap
rename to x-pack/plugins/spaces/public/management/spaces_grid/__snapshots__/spaces_grid_page.test.tsx.snap
diff --git a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_pages.test.tsx b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.test.tsx
similarity index 100%
rename from x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_pages.test.tsx
rename to x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.test.tsx
diff --git a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx
index ac57a566e2a00..a4f797e441ab5 100644
--- a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx
+++ b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx
@@ -180,53 +180,16 @@ export class SpacesGridPage extends Component {
showConfirmDeleteModal: false,
});
}}
- onConfirm={this.deleteSpace}
+ onSuccess={() => {
+ this.setState({
+ showConfirmDeleteModal: false,
+ });
+ this.loadGrid();
+ }}
/>
);
};
- public deleteSpace = async () => {
- const { spacesManager } = this.props;
-
- const space = this.state.selectedSpace;
-
- if (!space) {
- return;
- }
-
- this.setState({
- showConfirmDeleteModal: false,
- });
-
- try {
- await spacesManager.deleteSpace(space);
- } catch (error) {
- const { message: errorMessage = '' } = error.data || error.body || {};
-
- this.props.notifications.toasts.addDanger(
- i18n.translate('xpack.spaces.management.spacesGridPage.errorDeletingSpaceErrorMessage', {
- defaultMessage: 'Error deleting space: {errorMessage}',
- values: {
- errorMessage,
- },
- })
- );
- return;
- }
-
- this.loadGrid();
-
- const message = i18n.translate(
- 'xpack.spaces.management.spacesGridPage.spaceSuccessfullyDeletedNotificationMessage',
- {
- defaultMessage: 'Deleted "{spaceName}" space.',
- values: { spaceName: space.name },
- }
- );
-
- this.props.notifications.toasts.addSuccess(message);
- };
-
public loadGrid = async () => {
const { spacesManager, getFeatures, notifications } = this.props;
diff --git a/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx b/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx
index 76467bd838a10..23db78f6b8065 100644
--- a/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx
+++ b/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx
@@ -87,6 +87,7 @@ describe('spacesManagementApp', () => {
>
Spaces Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{"_isScalar":false}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/","search":"","hash":""}}}
+
`);
@@ -113,6 +114,7 @@ describe('spacesManagementApp', () => {
>
Spaces Edit Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{"_isScalar":false}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/create","search":"","hash":""}}}
+
`);
@@ -145,6 +147,7 @@ describe('spacesManagementApp', () => {
>
Spaces Edit Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{"_isScalar":false}},"spaceId":"some-space","history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/some-space","search":"","hash":""}}}
+
`);
diff --git a/x-pack/plugins/spaces/public/management/spaces_management_app.tsx b/x-pack/plugins/spaces/public/management/spaces_management_app.tsx
index da0f9157f310d..24b626c7c00e8 100644
--- a/x-pack/plugins/spaces/public/management/spaces_management_app.tsx
+++ b/x-pack/plugins/spaces/public/management/spaces_management_app.tsx
@@ -14,7 +14,10 @@ import type { StartServicesAccessor } from 'src/core/public';
import type { RegisterManagementAppArgs } from 'src/plugins/management/public';
import type { Space } from 'src/plugins/spaces_oss/common';
-import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public';
+import {
+ KibanaContextProvider,
+ RedirectAppLinks,
+} from '../../../../../src/plugins/kibana_react/public';
import type { PluginsStart } from '../plugin';
import type { SpacesManager } from '../spaces_manager';
@@ -36,22 +39,23 @@ export const spacesManagementApp = Object.freeze({
title,
async mount({ element, setBreadcrumbs, history }) {
- const [startServices, { SpacesGridPage }, { ManageSpacePage }] = await Promise.all([
+ const [
+ [coreStart, { features }],
+ { SpacesGridPage },
+ { ManageSpacePage },
+ ] = await Promise.all([
getStartServices(),
import('./spaces_grid'),
import('./edit_space'),
]);
- const [
- { notifications, i18n: i18nStart, application, chrome },
- { features },
- ] = startServices;
const spacesBreadcrumbs = [
{
text: title,
href: `/`,
},
];
+ const { notifications, i18n: i18nStart, application, chrome } = coreStart;
chrome.docTitle.change(title);
@@ -119,23 +123,25 @@ export const spacesManagementApp = Object.freeze({
};
render(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ,
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {' '}
+ ,
element
);