From 17f613040cf8f00c30c11263ba7e3debb49dc13e Mon Sep 17 00:00:00 2001 From: stanislavh Date: Fri, 13 Oct 2023 11:08:29 +0200 Subject: [PATCH] [NO-JIRA] Use submit on enter key in QP actions dialog --- .../__tests__/QualityProfilesApp-it.tsx | 2 +- .../components/ProfileModalForm.tsx | 24 ++++++----- .../sonar-web/src/main/js/hooks/useKeydown.ts | 42 +++++++++++++++++++ 3 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 server/sonar-web/src/main/js/hooks/useKeydown.ts diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/QualityProfilesApp-it.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/QualityProfilesApp-it.tsx index b6cdf9fae7d..3e30fd68b4b 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/QualityProfilesApp-it.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/QualityProfilesApp-it.tsx @@ -198,7 +198,7 @@ describe('Create', () => { await user.clear(ui.namePropupInput.get()); await user.type(ui.namePropupInput.get(), ui.newCQualityProfileName); await act(async () => { - await user.click(ui.modalExtendButton.get()); + await user.keyboard('{Enter}'); }); expect(await ui.headingNewCQualityProfile.find()).toBeInTheDocument(); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileModalForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileModalForm.tsx index a615de68270..b84b5f00cbc 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileModalForm.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileModalForm.tsx @@ -20,7 +20,9 @@ import { ButtonPrimary, FlagMessage, FormField, InputField, Modal } from 'design-system'; import * as React from 'react'; import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate, translateWithParameters } from '../../../helpers/l10n'; +import useKeyDown from '../../../hooks/useKeydown'; import { useProfileInheritanceQuery } from '../../../queries/quality-profiles'; import { Dict } from '../../../types/types'; import { Profile, ProfileActionModals } from '../types'; @@ -40,7 +42,7 @@ const LABELS_FOR_ACTION: Dict<{ button: string; header: string }> = { }; export default function ProfileModalForm(props: ProfileModalFormProps) { - const { action, loading, profile } = props; + const { action, loading, profile, onSubmit } = props; const [name, setName] = React.useState(''); const submitDisabled = loading || !name || name === profile.name; @@ -48,6 +50,14 @@ export default function ProfileModalForm(props: ProfileModalFormProps) { const { data: { ancestors } = {} } = useProfileInheritanceQuery(props.profile); + const handleSubmit = React.useCallback(() => { + if (name) { + onSubmit(name); + } + }, [name, onSubmit]); + + useKeyDown(handleSubmit, [KeyboardKeys.Enter]); + const extendsBuiltIn = ancestors?.some((profile) => profile.isBuiltIn); const showBuiltInWarning = (action === ProfileActionModals.Copy && !extendsBuiltIn) || @@ -57,6 +67,7 @@ export default function ProfileModalForm(props: ProfileModalFormProps) { @@ -93,7 +104,7 @@ export default function ProfileModalForm(props: ProfileModalFormProps) { setName(event.target.value)} + onChange={(event: React.ChangeEvent) => setName(event.target.value)} required size="full" type="text" @@ -103,14 +114,7 @@ export default function ProfileModalForm(props: ProfileModalFormProps) { } primaryButton={ - { - if (name) { - props.onSubmit(name); - } - }} - disabled={submitDisabled} - > + {translate(labels.button)} } diff --git a/server/sonar-web/src/main/js/hooks/useKeydown.ts b/server/sonar-web/src/main/js/hooks/useKeydown.ts new file mode 100644 index 00000000000..06b0c2f391a --- /dev/null +++ b/server/sonar-web/src/main/js/hooks/useKeydown.ts @@ -0,0 +1,42 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { useCallback, useEffect } from 'react'; +import { KeyboardKeys } from '../helpers/keycodes'; + +export default function useKeyDown(callback: Function, keys: Array) { + const onKeyDown = useCallback( + (event: KeyboardEvent) => { + const wasAnyKeyPressed = keys.some((key) => event.key === key); + if (wasAnyKeyPressed) { + event.preventDefault(); + callback(event); + } + }, + [callback, keys], + ); + + useEffect(() => { + document.addEventListener('keydown', onKeyDown); + return () => { + document.removeEventListener('keydown', onKeyDown); + }; + }, [onKeyDown]); +} -- 2.39.5