Skip to content

Commit fdb414b

Browse files
authored
Merge pull request #306 from NHSDigital/feature/CCM-8603-prevent-dbl-click
CCM-8603: prevent dbl click
2 parents 44f3669 + 3e55790 commit fdb414b

File tree

11 files changed

+103
-41
lines changed

11 files changed

+103
-41
lines changed

frontend/src/__tests__/app/create-and-submit-templates/__snapshots__/page.test.tsx.snap

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ exports[`matches the snapshot 1`] = `
6363
<a
6464
aria-disabled="false"
6565
class="nhsuk-button"
66-
data-testid="link-button"
6766
draggable="false"
6867
href="/templates/manage-templates"
6968
role="button"

frontend/src/__tests__/app/manage-templates/page.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ describe('ManageTemplatesPage', () => {
3535

3636
expect(screen.getByTestId('page-content-wrapper')).toBeInTheDocument();
3737
expect(screen.getByTestId('page-heading')).toBeInTheDocument();
38-
expect(screen.getByTestId('link-button')).toBeInTheDocument();
39-
expect(screen.getByTestId('link-button')).toHaveAttribute(
38+
expect(screen.getByRole('button')).toBeInTheDocument();
39+
expect(screen.getByRole('button')).toHaveAttribute(
4040
'href',
4141
manageTemplatesContent.createTemplateButton.url
4242
);
43-
expect(screen.getByTestId('link-button')).toHaveTextContent(
43+
expect(screen.getByRole('button')).toHaveTextContent(
4444
manageTemplatesContent.createTemplateButton.text
4545
);
4646

@@ -52,12 +52,12 @@ describe('ManageTemplatesPage', () => {
5252

5353
expect(screen.getByTestId('page-content-wrapper')).toBeInTheDocument();
5454
expect(screen.getByTestId('page-heading')).toBeInTheDocument();
55-
expect(screen.getByTestId('link-button')).toBeInTheDocument();
56-
expect(screen.getByTestId('link-button')).toHaveAttribute(
55+
expect(screen.getByRole('button')).toBeInTheDocument();
56+
expect(screen.getByRole('button')).toHaveAttribute(
5757
'href',
5858
manageTemplatesContent.createTemplateButton.url
5959
);
60-
expect(screen.getByTestId('link-button')).toHaveTextContent(
60+
expect(screen.getByRole('button')).toHaveTextContent(
6161
manageTemplatesContent.createTemplateButton.text
6262
);
6363

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,60 @@
1-
import { render, screen } from '@testing-library/react';
1+
import { fireEvent, render, screen } from '@testing-library/react';
22
import { NHSNotifyButton } from '@atoms/NHSNotifyButton/NHSNotifyButton';
3-
import { ButtonType } from '@atoms/NHSNotifyButton/button.types';
43

5-
const buttonProps: ButtonType = {
6-
children: 'Button text',
7-
};
8-
9-
describe('Footer component', () => {
4+
describe('NHS Notify button', () => {
105
it('renders component correctly as a button', () => {
11-
render(<NHSNotifyButton {...buttonProps} />);
6+
render(
7+
<NHSNotifyButton data-testid='button'> Button text</NHSNotifyButton>
8+
);
129

13-
expect(screen.getByTestId('link-button')).toBeInTheDocument();
14-
expect(screen.getByTestId('link-button')).toHaveTextContent('Button text');
10+
expect(screen.getByTestId('button')).toBeInTheDocument();
11+
expect(screen.getByTestId('button')).toHaveTextContent('Button text');
1512
});
1613

1714
it('renders component correctly as a link button', () => {
18-
const linkButtonProps: ButtonType = { ...buttonProps, href: '#' };
19-
render(<NHSNotifyButton {...linkButtonProps} />);
15+
render(
16+
<NHSNotifyButton data-testid='link-button' href='#'>
17+
{' '}
18+
Button text
19+
</NHSNotifyButton>
20+
);
2021

2122
expect(screen.getByTestId('link-button')).toBeInTheDocument();
2223
expect(screen.getByTestId('link-button')).toHaveTextContent('Button text');
2324
expect(screen.getByTestId('link-button')).toHaveAttribute('href', '#');
2425
});
26+
27+
it('debounces multiple clicks', async () => {
28+
const onClick = jest.fn();
29+
30+
render(
31+
<NHSNotifyButton data-testid='button' onClick={onClick}>
32+
{' '}
33+
Button text
34+
</NHSNotifyButton>
35+
);
36+
37+
const button = screen.getByTestId('button');
38+
39+
fireEvent.click(button);
40+
fireEvent.click(button);
41+
fireEvent.click(button);
42+
fireEvent.click(button);
43+
fireEvent.click(button);
44+
fireEvent.click(button);
45+
46+
expect(onClick).toHaveBeenCalledTimes(1);
47+
});
48+
49+
it('default onClick does nothing', async () => {
50+
const container = render(
51+
<NHSNotifyButton data-testid='button'>Button text</NHSNotifyButton>
52+
);
53+
54+
const button = screen.getByTestId('button');
55+
56+
fireEvent.click(button);
57+
58+
expect(container.asFragment()).toMatchSnapshot();
59+
});
2560
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`NHS Notify button default onClick does nothing 1`] = `
4+
<DocumentFragment>
5+
<button
6+
aria-disabled="false"
7+
class="nhsuk-button"
8+
data-testid="button"
9+
type="submit"
10+
>
11+
Button text
12+
</button>
13+
</DocumentFragment>
14+
`;

frontend/src/components/atoms/NHSNotifyButton/NHSNotifyButton.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
'use client';
22

33
import { Button } from 'nhsuk-react-components';
4-
import { ButtonType } from './button.types';
54

65
export function NHSNotifyButton({
76
children,
87
href,
98
...rest
10-
}: ButtonType & React.ComponentProps<typeof Button>) {
9+
}: React.ComponentProps<typeof Button>) {
1110
return (
12-
<Button {...rest} href={href} data-testid='link-button'>
11+
<Button
12+
preventDoubleClick
13+
debounceTimeout={10_000}
14+
onClick={() => {}}
15+
href={href}
16+
{...rest}
17+
>
1318
{children}
1419
</Button>
1520
);

frontend/src/components/forms/DeleteTemplate/DeleteTemplate.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { FC } from 'react';
44
import { useFormState } from 'react-dom';
55
import { ChannelTemplate } from 'nhs-notify-web-template-management-utils';
66
import { deleteTemplatePageContent } from '@content/content';
7-
import { Button } from 'nhsuk-react-components';
87
import { NHSNotifyMain } from '@atoms/NHSNotifyMain/NHSNotifyMain';
98
import { NHSNotifyFormWrapper } from '@molecules/NHSNotifyFormWrapper/NHSNotifyFormWrapper';
9+
import { NHSNotifyButton } from '@atoms/NHSNotifyButton/NHSNotifyButton';
1010
import {
1111
deleteTemplateYesAction,
1212
deleteTemplateNoAction,
@@ -37,14 +37,16 @@ export const DeleteTemplate: FC<DeleteTemplateProps> = ({ template }) => {
3737
style: { display: 'inline' },
3838
}}
3939
>
40-
<Button secondary>{noButtonText}</Button>
40+
<NHSNotifyButton secondary>{noButtonText}</NHSNotifyButton>
4141
</NHSNotifyFormWrapper>
4242
<NHSNotifyFormWrapper
4343
action={action}
4444
formAttributes={{ style: { display: 'inline' } }}
4545
formId='delete-template-yes'
4646
>
47-
<Button className='nhsuk-button--warning'>{yesButtonText}</Button>
47+
<NHSNotifyButton className='nhsuk-button--warning'>
48+
{yesButtonText}
49+
</NHSNotifyButton>
4850
</NHSNotifyFormWrapper>
4951
</div>
5052
</div>

frontend/src/components/forms/EmailTemplateForm/EmailTemplateForm.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
HintText,
88
Label,
99
Textarea,
10-
Button,
1110
BackLink,
1211
} from 'nhsuk-react-components';
1312
import { getBasePath } from '@utils/get-base-path';
@@ -28,6 +27,7 @@ import { FormSection } from '@molecules/FormSection/FormSection';
2827
import { useTextInput } from '@hooks/use-text-input.hook';
2928
import { ChannelGuidance } from '@molecules/ChannelGuidance/ChannelGuidance';
3029
import { NHSNotifyMain } from '@atoms/NHSNotifyMain/NHSNotifyMain';
30+
import { NHSNotifyButton } from '@atoms/NHSNotifyButton/NHSNotifyButton';
3131

3232
export const EmailTemplateForm: FC<
3333
PageComponentProps<EmailTemplate | Draft<EmailTemplate>>
@@ -133,9 +133,12 @@ export const EmailTemplateForm: FC<
133133
data-testid='emailTemplateMessage-input'
134134
/>
135135
</FormSection>
136-
<Button type='submit' id='create-email-template-submit-button'>
136+
<NHSNotifyButton
137+
type='submit'
138+
id='create-email-template-submit-button'
139+
>
137140
{buttonText}
138-
</Button>
141+
</NHSNotifyButton>
139142
</NHSNotifyFormWrapper>
140143
</div>
141144
<div className='nhsuk-grid-column-one-third'>

frontend/src/components/forms/NhsAppTemplateForm/NhsAppTemplateForm.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
HintText,
88
Label,
99
Textarea,
10-
Button,
1110
BackLink,
1211
} from 'nhsuk-react-components';
1312
import { getBasePath } from '@utils/get-base-path';
@@ -28,6 +27,7 @@ import { useTextInput } from '@hooks/use-text-input.hook';
2827
import { useJsEnabledStyle } from '@hooks/use-js-enabled-style.hook';
2928
import { ChannelGuidance } from '@molecules/ChannelGuidance/ChannelGuidance';
3029
import { NHSNotifyMain } from '@atoms/NHSNotifyMain/NHSNotifyMain';
30+
import { NHSNotifyButton } from '@atoms/NHSNotifyButton/NHSNotifyButton';
3131

3232
export const NhsAppTemplateForm: FC<
3333
PageComponentProps<NHSAppTemplate | Draft<NHSAppTemplate>>
@@ -103,9 +103,9 @@ export const NhsAppTemplateForm: FC<
103103
{nhsAppTemplateMessage.length}
104104
{characterCountText}
105105
</p>
106-
<Button type='submit' id='create-nhs-app-template-submit-button'>
106+
<NHSNotifyButton id='create-nhs-app-template-submit-button'>
107107
{buttonText}
108-
</Button>
108+
</NHSNotifyButton>
109109
</NHSNotifyFormWrapper>
110110
</div>
111111
<div className='nhsuk-grid-column-one-third'>

frontend/src/components/forms/SmsTemplateForm/SmsTemplateForm.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { MessageFormatting } from '@molecules/MessageFormatting/MessageFormattin
66
import { NHSNotifyFormWrapper } from '@molecules/NHSNotifyFormWrapper/NHSNotifyFormWrapper';
77
import { Personalisation } from '@molecules/Personalisation/Personalisation';
88
import {
9-
Button,
109
HintText,
1110
Label,
1211
Textarea,
@@ -28,6 +27,7 @@ import { createSmsTemplatePageContent as content } from '@content/content';
2827
import { MAX_SMS_CHARACTER_LENGTH } from '@utils/constants';
2928
import { ChannelGuidance } from '@molecules/ChannelGuidance/ChannelGuidance';
3029
import { NHSNotifyMain } from '@atoms/NHSNotifyMain/NHSNotifyMain';
30+
import { NHSNotifyButton } from '@atoms/NHSNotifyButton/NHSNotifyButton';
3131
import { processFormActions } from './server-action';
3232
import { calculateHowManySmsMessages } from './view-actions';
3333

@@ -111,9 +111,9 @@ export const SmsTemplateForm: FC<
111111
{content.smsPricingText}
112112
</a>
113113
</p>
114-
<Button id='create-sms-template-submit-button'>
114+
<NHSNotifyButton id='create-sms-template-submit-button'>
115115
{content.buttonText}
116-
</Button>
116+
</NHSNotifyButton>
117117
</NHSNotifyFormWrapper>
118118
</div>
119119
<div className='nhsuk-grid-column-one-third'>

frontend/src/components/forms/SubmitTemplate/SubmitTemplate.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
'use client';
22

33
import { FC } from 'react';
4-
import { WarningCallout, Button } from 'nhsuk-react-components';
4+
import { WarningCallout } from 'nhsuk-react-components';
55
import { SubmitTemplatePageComponentProps } from 'nhs-notify-web-template-management-utils';
66
import { submitTemplateContent } from '@content/content';
77
import { NHSNotifyFormWrapper } from '@molecules/NHSNotifyFormWrapper/NHSNotifyFormWrapper';
88
import { getBasePath } from '@utils/get-base-path';
99
import { submitTemplate } from '@forms/SubmitTemplate/server-action';
1010
import { NHSNotifyMain } from '@atoms/NHSNotifyMain/NHSNotifyMain';
11+
import { NHSNotifyButton } from '@atoms/NHSNotifyButton/NHSNotifyButton';
1112

1213
export const SubmitTemplate: FC<SubmitTemplatePageComponentProps> = ({
1314
templateName,
@@ -60,15 +61,17 @@ export const SubmitTemplate: FC<SubmitTemplatePageComponentProps> = ({
6061
value={templateId}
6162
readOnly
6263
/>
63-
<Button
64+
<NHSNotifyButton
6465
secondary
6566
id='go-back-button'
6667
className='nhsuk-u-margin-right-3'
6768
href={`${getBasePath()}/${goBackPath}/${templateId}`}
6869
>
6970
{goBackButtonText}
70-
</Button>
71-
<Button id='submit-template-button'>{buttonText}</Button>
71+
</NHSNotifyButton>
72+
<NHSNotifyButton id='submit-template-button'>
73+
{buttonText}
74+
</NHSNotifyButton>
7275
</NHSNotifyFormWrapper>
7376
</div>
7477
</div>

0 commit comments

Comments
 (0)