diff --git a/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.scss b/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.scss new file mode 100644 index 0000000..acd9576 --- /dev/null +++ b/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.scss @@ -0,0 +1 @@ +@import '~@redhat-cloud-services/frontend-components-utilities/styles/variables'; diff --git a/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.test.tsx b/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.test.tsx new file mode 100644 index 0000000..82d03c2 --- /dev/null +++ b/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.test.tsx @@ -0,0 +1,77 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import AutoJoinChangeConfirmDialog from './AutoJoinChangeConfirmDialog'; +import '@testing-library/jest-dom'; +import { Domain, DomainType } from '../../Api'; + +const domain: Domain = { + title: 'domain', + description: 'description', + auto_enrollment_enabled: true, + domain_id: '1', + domain_name: 'domain', + domain_type: DomainType.RhelIdm, +}; + +test('expect that it does not crash with undefined domain', () => { + // When rendered with undefined domain + const { container } = render(); + + // Then the dialog should not be displayed + expect(container).toBeEmptyDOMElement(); +}); + +test('expect empty when isOpen is false', () => { + // When rendered with isOpen false + const { container } = render(); + + // Then the dialog should not be displayed + expect(container).toBeEmptyDOMElement(); +}); + +test('expect modal displayed - disable', () => { + // Given a domain with auto_enrollment_enabled true + expect(domain.auto_enrollment_enabled).toBe(true); + + // When rendered with isOpen true and auto_enrollment_enabled true + render(); + + // Then the disable dialog should be displayed + expect(screen.getByRole('heading')).toHaveTextContent('Disable domain auto-join on launch'); +}); + +test('expect modal displayed - enable', () => { + // Given a domain with auto_enrollment_enabled false + const domain2 = { ...domain, auto_enrollment_enabled: false }; + + // When rendered with isOpen + render(); + + // Then the enable dialog should be displayed + expect(screen.getByRole('heading')).toHaveTextContent('Enable domain auto-join on launch'); +}); + +test('expect handlers to be called', () => { + // given + const confirmHandler = jest.fn(); + const cancelHandler = jest.fn(); + render(); + + // when the OK button is clicked + screen.getByRole('button', { name: 'OK' }).click(); + + // then the confirmHandler should be called with the domain as argument and cancelHandler should not be called + expect(confirmHandler).toBeCalledWith(domain); + expect(cancelHandler).toBeCalledTimes(0); + + // given mocks are cleared + confirmHandler.mockClear(); + cancelHandler.mockClear(); + + // when the dialog Cancel button is clicked + screen.getByRole('button', { name: 'Cancel' }).click(); + + // then the confirmHandler should not be called and cancelHandler should be called + expect(confirmHandler).toBeCalledTimes(0); + expect(cancelHandler).toBeCalledTimes(1); +}); diff --git a/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.tsx b/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.tsx new file mode 100644 index 0000000..6aa89ae --- /dev/null +++ b/src/Components/AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { Button, Modal } from '@patternfly/react-core'; +import './AutoJoinChangeConfirmDialog.scss'; + +import { Domain } from '../../Api/api'; + +interface AutoJoinChangeConfirmDialogProps { + /** The domain to be changed */ + domain?: Domain; + /** Flag to open the dialog */ + isOpen: boolean; + /** Event fired when the user confirms the change */ + onConfirm?: (domain?: Domain) => void; + /** Event fired when the user cancels the change */ + onCancel?: () => void; +} + +/** + * Modal dialog to confirm a change in domain auto-join. + * + * @param props + */ +const AutoJoinChangeConfirmDialog: React.FC = (props) => { + if (!props.domain) { + return <>; + } + + const domain = props.domain; + + const onConfirmWrapper = () => { + props.onConfirm !== undefined && props.onConfirm(domain); + }; + + let title = ''; + let text: React.ReactNode = ''; + if (domain.auto_enrollment_enabled) { + title = `Disable domain auto-join on launch`; + text = ( +
+

Are you sure you want to disable domain auto-join?

+

Disabling will avoid new hosts to join the domain "{domain.title}" using domain auto-join on launch.

+
+ ); + } else { + title = `Enable domain auto-join on launch`; + text = ( +
+

Are you sure you want to enable domain auto-join?

+

Enabling will allow new hosts to join the domain "{domain.title}" using domain auto-join on launch.

+
+ ); + } + + return ( + + OK + , + , + ]} + > + {text} + + ); +}; + +export default AutoJoinChangeConfirmDialog; diff --git a/src/Components/DomainList/DomainList.tsx b/src/Components/DomainList/DomainList.tsx index a762f9f..d3c9c6a 100644 --- a/src/Components/DomainList/DomainList.tsx +++ b/src/Components/DomainList/DomainList.tsx @@ -1,12 +1,13 @@ import { ActionsColumn, IAction, TableComposable, Tbody, Td, Th, ThProps, Thead, Tr } from '@patternfly/react-table'; import './DomainList.scss'; -import { Fragment, useContext } from 'react'; +import { Fragment, useContext, useState } from 'react'; import React from 'react'; import { Domain, DomainType, ResourcesApiFactory } from '../../Api/api'; import { useNavigate } from 'react-router-dom'; import { AppContext, AppContextType } from '../../AppContext'; import { Button } from '@patternfly/react-core'; +import AutoJoinChangeConfirmDialog from '../AutoJoinChangeConfirmDialog/AutoJoinChangeConfirmDialog'; export interface IColumnType { key: string; @@ -107,6 +108,9 @@ export const DomainList = () => { const [activeSortDirection, setActiveSortDirection] = React.useState<'asc' | 'desc'>('asc'); const domains = context?.domains || ([] as Domain[]); + const [isOpenAutoJoinChangeConfirm, setIsOpenAutoJoinChangeConfirm] = useState(false); + const [currentDomain, setCurrentDomain] = useState(); + const enabledText = 'Enabled'; const disabledText = 'Disabled'; @@ -128,8 +132,21 @@ export const DomainList = () => { context?.deleteDomain(uuid); }; - const onEnableDisable = (domain: Domain) => { - console.log(`clicked on Enable/Disable, on row ${domain.title}`); + const showAutoJoinChangeConfirmDialog = (domain: Domain) => { + setCurrentDomain(domain); + setIsOpenAutoJoinChangeConfirm(true); + }; + + const onConfirmAutoJoinChange = (domain?: Domain) => { + console.log('onConfirmAutoJoinChange'); + setIsOpenAutoJoinChangeConfirm(false); + if (domain) { + toggleAutoJoin(domain); + } + }; + + const toggleAutoJoin = (domain: Domain) => { + console.log(`toggling auto_enrollment_enabled of domain: ${domain?.title}`); if (domain.domain_id) { resources_api .updateDomainUser(domain.domain_id, { @@ -171,7 +188,7 @@ export const DomainList = () => { const defaultActions = (domain: Domain): IAction[] => [ { title: 'Enable/Disable', - onClick: () => onEnableDisable(domain), + onClick: () => showAutoJoinChangeConfirmDialog(domain), ouiaId: 'ButtonActionEnableDisable', }, { @@ -246,6 +263,12 @@ export const DomainList = () => { })} + setIsOpenAutoJoinChangeConfirm(false)} + /> ); };