ConfirmModal: Pressing enter in confirmation input now triggers primary action (#85812)

wrap confirm modal in a form
This commit is contained in:
Ashley Harrison 2024-04-10 09:22:22 +01:00 committed by GitHub
parent 8f5839fe8f
commit bbf874b96d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 65 additions and 32 deletions

View File

@ -105,6 +105,32 @@ describe('ConfirmModal', () => {
expect(mockOnConfirm).toHaveBeenCalled();
});
it('typing the confirmation text and pressing enter should trigger the primary action', async () => {
render(
<ConfirmModal
title="Some Title"
body="Some Body"
confirmText="Please Confirm"
alternativeText="Alternative Text"
dismissText="Dismiss Text"
isOpen={true}
confirmationText="My confirmation text"
onConfirm={mockOnConfirm}
onDismiss={() => {}}
onAlternative={() => {}}
/>
);
expect(screen.getByRole('button', { name: 'Please Confirm' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Please Confirm' })).toBeDisabled();
await user.type(screen.getByPlaceholderText('Type "My confirmation text" to confirm'), 'mY CoNfIrMaTiOn TeXt');
expect(screen.getByRole('button', { name: 'Please Confirm' })).toBeEnabled();
await user.type(screen.getByPlaceholderText('Type "My confirmation text" to confirm'), '{enter}');
expect(mockOnConfirm).toHaveBeenCalled();
});
it('returning a promise in the onConfirm callback disables the button whilst the callback is in progress', async () => {
mockOnConfirm.mockImplementation(() => {
return new Promise((resolve) => {
@ -136,7 +162,9 @@ describe('ConfirmModal', () => {
await user.click(screen.getByRole('button', { name: 'Please Confirm' }));
expect(mockOnConfirm).toHaveBeenCalled();
expect(screen.getByRole('button', { name: 'Please Confirm' })).toBeDisabled();
await waitFor(() => {
expect(screen.getByRole('button', { name: 'Please Confirm' })).toBeDisabled();
});
jest.runAllTimers();
await waitFor(() => {

View File

@ -1,5 +1,6 @@
import { css, cx } from '@emotion/css';
import React, { useEffect, useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
@ -96,40 +97,44 @@ export const ConfirmModal = ({
}
};
const { handleSubmit } = useForm();
return (
<Modal className={cx(styles.modal, modalClass)} title={title} icon={icon} isOpen={isOpen} onDismiss={onDismiss}>
<div className={styles.modalText}>
{body}
{description ? <div className={styles.modalDescription}>{description}</div> : null}
{confirmationText ? (
<div className={styles.modalConfirmationInput}>
<Stack alignItems="flex-start">
<Box>
<Input placeholder={`Type "${confirmationText}" to confirm`} onChange={onConfirmationTextChange} />
</Box>
</Stack>
</div>
) : null}
</div>
<Modal.ButtonRow>
<Button variant={dismissVariant} onClick={onDismiss} fill="outline">
{dismissText}
</Button>
<Button
variant={confirmButtonVariant}
onClick={onConfirmClick}
disabled={disabled}
ref={buttonRef}
data-testid={selectors.pages.ConfirmModal.delete}
>
{confirmText}
</Button>
{onAlternative ? (
<Button variant="primary" onClick={onAlternative}>
{alternativeText}
<form onSubmit={handleSubmit(onConfirmClick)}>
<div className={styles.modalText}>
{body}
{description ? <div className={styles.modalDescription}>{description}</div> : null}
{confirmationText ? (
<div className={styles.modalConfirmationInput}>
<Stack alignItems="flex-start">
<Box>
<Input placeholder={`Type "${confirmationText}" to confirm`} onChange={onConfirmationTextChange} />
</Box>
</Stack>
</div>
) : null}
</div>
<Modal.ButtonRow>
<Button variant={dismissVariant} onClick={onDismiss} fill="outline">
{dismissText}
</Button>
) : null}
</Modal.ButtonRow>
<Button
type="submit"
variant={confirmButtonVariant}
disabled={disabled}
ref={buttonRef}
data-testid={selectors.pages.ConfirmModal.delete}
>
{confirmText}
</Button>
{onAlternative ? (
<Button variant="primary" onClick={onAlternative}>
{alternativeText}
</Button>
) : null}
</Modal.ButtonRow>
</form>
</Modal>
);
};