Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(HMS-2994): delete domain confirmation #49

Merged
merged 1 commit into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import '~@redhat-cloud-services/frontend-components-utilities/styles/variables';
50 changes: 50 additions & 0 deletions src/Components/ConfirmDeleteDomain/ConfirmDeleteDomain.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import ConfirmDeleteDomain from './ConfirmDeleteDomain';
import '@testing-library/jest-dom';
import { Domain } from '../../Api';

const domain: Domain = {
domain_name: 'mydomain.test',
} as unknown as Domain;

test('expect empty when isOpen is false', () => {
const root = render(<ConfirmDeleteDomain domain={domain} isOpen={false} />);
expect(root.container).toBeEmptyDOMElement();
});

test('expect modal displayed', () => {
render(<ConfirmDeleteDomain domain={domain} isOpen={true} />);
expect(screen.getByRole('heading')).toHaveTextContent(/^Warning alert:Delete identity domain registration\?$/);
expect(screen.getByRole('button', { name: 'Close' })).toHaveTextContent(/^$/);
expect(screen.getByRole('button', { name: 'Delete' })).toHaveTextContent(/^Delete$/);
expect(screen.getByRole('button', { name: 'Cancel' })).toHaveTextContent(/^Cancel$/);
});

test('expect handler onDelete to be called', () => {
// given
const confirmHandler = jest.fn();
const cancelHandler = jest.fn();
render(<ConfirmDeleteDomain domain={domain} isOpen={true} onDelete={confirmHandler} onCancel={cancelHandler} />);

// when the OK button is clicked
screen.getByRole('button', { name: 'Delete' }).click();

// then the confirmHandler should be called with the domain as argument and cancelHandler should not
expect(confirmHandler).toBeCalledWith(domain);
expect(cancelHandler).toBeCalledTimes(0);
});

test('expect handler onCancel to be called', () => {
// given
const confirmHandler = jest.fn();
const cancelHandler = jest.fn();
render(<ConfirmDeleteDomain domain={domain} isOpen={true} onDelete={confirmHandler} onCancel={cancelHandler} />);

// when the OK button is clicked
screen.getByRole('button', { name: 'Cancel' }).click();

// then the confirmHandler should be called with the domain as argument and cancelHandler should not
expect(cancelHandler).toBeCalledTimes(1);
expect(confirmHandler).toBeCalledTimes(0);
});
44 changes: 44 additions & 0 deletions src/Components/ConfirmDeleteDomain/ConfirmDeleteDomain.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Button, Modal } from '@patternfly/react-core';
import './ConfirmDeleteDomain.scss';
import React from 'react';
import { Domain } from '../../Api/api';

interface ConfirmDeleteDomainProps {
domain?: Domain;
isOpen?: boolean;
onDelete?: (domain?: Domain) => void;
onCancel?: () => void;
}

/**
* Modal dialog to confirm a domain deletion.
*
* @param props the props given by the smart component.
*/
const ConfirmDeleteDomain: React.FC<ConfirmDeleteDomainProps> = (props) => {
const onDeleteWrapper = () => {
props.onDelete && props.onDelete(props.domain);
};
return (
<Modal
isOpen={props.isOpen}
titleIconVariant={'warning'}
variant="small"
title="Delete identity domain registration?"
ouiaId="ModalConfirmDeletion"
onClose={props.onCancel}
actions={[
<Button key="delete" variant="danger" onClick={onDeleteWrapper} ouiaId="ButtonModalConfirmDeletionDelete">
Delete
</Button>,
<Button key="cancel" variant="link" onClick={props.onCancel} ouiaId="ButtonModalConfirmDeletionCancel">
Cancel
</Button>,
]}
>
No new host enrollment from HCC will be allowed on <b>{props.domain?.title || ''}</b> domain after registration deletion.
</Modal>
);
};

export default ConfirmDeleteDomain;
20 changes: 17 additions & 3 deletions src/Components/DomainList/DomainList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useNavigate } from 'react-router-dom';
import { AppContext, AppContextType } from '../../AppContext';
import { Button } from '@patternfly/react-core';
import AutoJoinChangeConfirmDialog from '../AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog';
import ConfirmDeleteDomain from '../ConfirmDeleteDomain/ConfirmDeleteDomain';

export interface IColumnType<T> {
key: string;
Expand Down Expand Up @@ -108,7 +109,9 @@ export const DomainList = () => {
const [activeSortDirection, setActiveSortDirection] = React.useState<'asc' | 'desc'>('asc');

const domains = context?.domains || ([] as Domain[]);

const [isOpenAutoJoinChangeConfirm, setIsOpenAutoJoinChangeConfirm] = useState(false);
const [isOpenConfirmDelete, setIsOpenConfirmDelete] = useState<boolean>(false);
const [currentDomain, setCurrentDomain] = useState<Domain>();

const enabledText = 'Enabled';
Expand Down Expand Up @@ -166,8 +169,18 @@ export const DomainList = () => {
}
};

const onDelete = (domain: Domain) => {
if (domain.domain_id !== undefined) {
const OnShowConfirmDelete = (domain: Domain) => {
setIsOpenConfirmDelete(true);
setCurrentDomain(domain);
};

const onDismissConfirmDelete = () => {
setIsOpenConfirmDelete(false);
};

const onDelete = (domain?: Domain) => {
setIsOpenConfirmDelete(false);
if (domain?.domain_id !== undefined) {
const domainId = domain.domain_id;
resources_api
.deleteDomain(domainId)
Expand Down Expand Up @@ -198,7 +211,7 @@ export const DomainList = () => {
},
{
title: 'Delete',
onClick: () => onDelete(domain),
onClick: () => OnShowConfirmDelete(domain),
ouiaId: 'ButtonActionDelete',
},
];
Expand Down Expand Up @@ -269,6 +282,7 @@ export const DomainList = () => {
onConfirm={onConfirmAutoJoinChange}
onCancel={() => setIsOpenAutoJoinChangeConfirm(false)}
/>
<ConfirmDeleteDomain domain={currentDomain} isOpen={isOpenConfirmDelete} onCancel={onDismissConfirmDelete} onDelete={onDelete} />
</>
);
};
Expand Down
51 changes: 34 additions & 17 deletions src/Routes/DetailPage/DetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import { AppContext, AppContextType } from '../../AppContext';
import { DetailGeneral } from './Components/DetailGeneral/DetailGeneral';
import { DetailServers } from './Components/DetailServers/DetailServers';
import ConfirmDeleteDomain from '../../Components/ConfirmDeleteDomain/ConfirmDeleteDomain';

/**
* It represents the detail page to show the information about a
Expand All @@ -40,6 +41,7 @@

// States
const [domain, setDomain] = useState<Domain | undefined>(appContext?.getDomain(domain_id || ''));
const [isOpenConfirmDelete, setIsOpenConfirmDelete] = useState<boolean>(false);

console.log('INFO:DetailPage render:domain_id=' + domain_id);

Expand Down Expand Up @@ -71,7 +73,7 @@

const onKebabToggle = (
isOpen: boolean,
event: MouseEvent | TouchEvent | KeyboardEvent | React.KeyboardEvent<any> | React.MouseEvent<HTMLButtonElement>

Check warning on line 76 in src/Routes/DetailPage/DetailPage.tsx

View workflow job for this annotation

GitHub Actions / validate

Unexpected any. Specify a different type
) => {
event.stopPropagation();
setIsKebabOpen(isOpen);
Expand All @@ -82,26 +84,40 @@
setIsKebabOpen(!isKebabOpen);
};

const OnShowConfirmDelete = () => {
setIsOpenConfirmDelete(true);
};

const onDismissConfirmDelete = () => {
setIsOpenConfirmDelete(false);
};

const onDelete = (domain?: Domain) => {
if (domain?.domain_id !== undefined) {
const domainId = domain.domain_id;
resources_api
.deleteDomain(domainId)
.then((response) => {
if (response.status == 204) {
appContext?.deleteDomain(domainId);
navigate('/domains', { replace: true });
} else {
// TODO show-up notification with error message
console.error(`response.status=${response.status}; response.data=${response.data}`);
}
})
.catch((error) => {
// TODO show-up notification with error message
console.log('error onClose: ' + error);
});
}
};

const dropdownItems: JSX.Element[] = [
<DropdownItem
key="delete"
onClick={(value) => {
console.log('Deleting domain: ' + value);
if (domain_id !== undefined) {
resources_api
.deleteDomain(domain_id)
.then((res) => {
if (res.status === 204) {
console.info('Domain ' + value + ' was deleted');
appContext?.deleteDomain(domain_id);
pvoborni marked this conversation as resolved.
Show resolved Hide resolved
navigate('/domains', { replace: true });
}
})
.catch((reason) => {
// TODO Send error notification to chrome
console.log(reason);
});
}
onClick={() => {
domain !== undefined && OnShowConfirmDelete();
}}
ouiaId="ButtonDetailsDelete"
>
Expand All @@ -111,7 +127,7 @@

// Tabs
const [activeTabKey, setActiveTabKey] = React.useState<string | number>(0);
const handleTabClick = (event: React.MouseEvent<any> | React.KeyboardEvent | MouseEvent, tabIndex: string | number) => {

Check warning on line 130 in src/Routes/DetailPage/DetailPage.tsx

View workflow job for this annotation

GitHub Actions / validate

Unexpected any. Specify a different type
setActiveTabKey(tabIndex);
};

Expand Down Expand Up @@ -168,6 +184,7 @@
</Card>
</PageSection>
</Page>
<ConfirmDeleteDomain domain={domain} isOpen={isOpenConfirmDelete} onCancel={onDismissConfirmDelete} onDelete={onDelete} />
</>
);
};
Expand Down
Loading