]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20366 Migrate profile Copy/Extend/Rename modal to MIUI
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Tue, 5 Sep 2023 14:57:52 +0000 (16:57 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 12 Sep 2023 20:02:40 +0000 (20:02 +0000)
server/sonar-web/src/main/js/apps/quality-profiles/__tests__/QualityProfileApp-it.tsx
server/sonar-web/src/main/js/apps/quality-profiles/__tests__/QualityProfilesApp-it.tsx
server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileModalForm.tsx

index 7f8209579f8612ea3b32e21896df588a4e3a2901..8898e911e56822c51ce8dc3fa0238d14ed212fa1 100644 (file)
@@ -39,22 +39,8 @@ const ui = {
   grantPermissionButton: byRole('button', {
     name: 'quality_profiles.grant_permissions_to_more_users',
   }),
-  grantPermissionDialog: byRole('dialog', {
-    name: 'quality_profiles.grant_permissions_to_user_or_group',
-  }),
-  removeGroupDialog: byRole('dialog', {
-    name: 'quality_profiles.permissions.remove.group',
-  }),
-  removeUserDialog: byRole('dialog', {
-    name: 'quality_profiles.permissions.remove.user',
-  }),
-  deleteProfileDialog: byRole('dialog', { name: 'quality_profiles.delete_confirm_title' }),
-  changeProjectsDialog: byRole('dialog', { name: 'projects' }),
-  changeParentDialog: byRole('dialog', { name: 'quality_profiles.change_parent' }),
-  extendDialog: byRole('dialog', { name: /quality_profiles.extend_x_title/ }),
-  copyDialog: byRole('dialog', { name: /quality_profiles.copy_x_title/ }),
-  renameDialog: byRole('dialog', { name: /quality_profiles.rename_x_title/ }),
-  selectparent: byRole('combobox', { name: /quality_profiles.parent/ }),
+  dialog: byRole('dialog'),
+  selectField: byRole('combobox'),
   selectUserOrGroup: byRole('combobox', { name: 'quality_profiles.search_description' }),
   twitterCheckbox: byRole('checkbox', { name: 'Twitter Twitter' }),
   benflixCheckbox: byRole('checkbox', { name: 'Benflix Benflix' }),
@@ -112,7 +98,7 @@ describe('Admin or user with permission', () => {
       await act(async () => {
         await user.click(ui.grantPermissionButton.get());
       });
-      expect(ui.grantPermissionDialog.get()).toBeInTheDocument();
+      expect(ui.dialog.get()).toBeInTheDocument();
       await selectEvent.select(ui.selectUserOrGroup.get(), 'Buzz');
       await user.click(ui.addButton.get());
       expect(ui.permissionSection.byText('Buzz').get()).toBeInTheDocument();
@@ -123,7 +109,7 @@ describe('Admin or user with permission', () => {
           .byRole('button', { name: 'quality_profiles.permissions.remove.user_x.Buzz' })
           .get()
       );
-      expect(ui.removeUserDialog.get()).toBeInTheDocument();
+      expect(ui.dialog.get()).toBeInTheDocument();
       await user.click(ui.removeButton.get());
       expect(ui.permissionSection.byText('buzz').query()).not.toBeInTheDocument();
     });
@@ -138,7 +124,7 @@ describe('Admin or user with permission', () => {
       await act(async () => {
         await user.click(ui.grantPermissionButton.get());
       });
-      expect(ui.grantPermissionDialog.get()).toBeInTheDocument();
+      expect(ui.dialog.get()).toBeInTheDocument();
       await selectEvent.select(ui.selectUserOrGroup.get(), 'ACDC');
       await user.click(ui.addButton.get());
       expect(ui.permissionSection.byText('ACDC').get()).toBeInTheDocument();
@@ -149,7 +135,7 @@ describe('Admin or user with permission', () => {
           .byRole('button', { name: 'quality_profiles.permissions.remove.group_x.ACDC' })
           .get()
       );
-      expect(ui.removeGroupDialog.get()).toBeInTheDocument();
+      expect(ui.dialog.get()).toBeInTheDocument();
       await user.click(ui.removeButton.get());
       expect(ui.permissionSection.byText('ACDC').query()).not.toBeInTheDocument();
     });
@@ -169,7 +155,7 @@ describe('Admin or user with permission', () => {
       expect(await ui.projectSection.find()).toBeInTheDocument();
       expect(ui.projectSection.byText('Twitter').query()).not.toBeInTheDocument();
       await user.click(ui.changeProjectsButton.get());
-      expect(ui.changeProjectsDialog.get()).toBeInTheDocument();
+      expect(ui.dialog.get()).toBeInTheDocument();
 
       await user.click(ui.withoutFilterButton.get());
       await user.click(ui.twitterCheckbox.get());
@@ -184,7 +170,7 @@ describe('Admin or user with permission', () => {
       expect(await ui.projectSection.find()).toBeInTheDocument();
       expect(ui.projectSection.byText('Benflix').get()).toBeInTheDocument();
       await user.click(ui.changeProjectsButton.get());
-      expect(ui.changeProjectsDialog.get()).toBeInTheDocument();
+      expect(ui.dialog.get()).toBeInTheDocument();
 
       await user.click(ui.benflixCheckbox.get());
       await user.click(ui.closeButton.get());
@@ -241,11 +227,11 @@ describe('Admin or user with permission', () => {
       expect(ui.inheritanceSection.byText('PHP way').get()).toBeInTheDocument();
 
       await user.click(ui.changeParentButton.get());
-      expect(await ui.changeParentDialog.find()).toBeInTheDocument();
+      expect(await ui.dialog.find()).toBeInTheDocument();
       expect(ui.changeButton.get()).toBeDisabled();
-      await selectEvent.select(ui.selectparent.get(), 'PHP Sonar way 2');
+      await selectEvent.select(ui.selectField.get(), 'PHP Sonar way 2');
       await user.click(ui.changeButton.get());
-      expect(ui.changeParentDialog.query()).not.toBeInTheDocument();
+      expect(ui.dialog.query()).not.toBeInTheDocument();
 
       // Parents
       expect(ui.inheritanceSection.byText('PHP Sonar way 2').get()).toBeInTheDocument();
@@ -284,16 +270,16 @@ describe('Admin or user with permission', () => {
       await user.click(ui.qualityProfileActions.get());
       await user.click(ui.extendButton.get());
 
-      expect(ui.extendDialog.get()).toBeInTheDocument();
-      expect(ui.extendDialog.byRole('button', { name: 'extend' }).get()).toBeDisabled();
+      expect(ui.dialog.get()).toBeInTheDocument();
+      expect(ui.dialog.byRole('button', { name: 'extend' }).get()).toBeDisabled();
 
       await user.clear(ui.newNameInput.get());
       await user.type(ui.newNameInput.get(), 'Bad new PHP quality profile');
       await act(async () => {
-        await user.click(ui.extendDialog.byRole('button', { name: 'extend' }).get());
+        await user.click(ui.dialog.byRole('button', { name: 'extend' }).get());
       });
 
-      expect(ui.extendDialog.query()).not.toBeInTheDocument();
+      expect(ui.dialog.query()).not.toBeInTheDocument();
 
       expect(screen.getAllByText('Bad new PHP quality profile')).toHaveLength(2);
       expect(screen.getAllByText('Good old PHP quality profile')).toHaveLength(2);
@@ -306,16 +292,16 @@ describe('Admin or user with permission', () => {
       await user.click(await ui.qualityProfileActions.find());
       await user.click(ui.copyButton.get());
 
-      expect(ui.copyDialog.get()).toBeInTheDocument();
-      expect(ui.copyDialog.byRole('button', { name: 'copy' }).get()).toBeDisabled();
+      expect(ui.dialog.get()).toBeInTheDocument();
+      expect(ui.dialog.byRole('button', { name: 'copy' }).get()).toBeDisabled();
 
       await user.clear(ui.newNameInput.get());
       await user.type(ui.newNameInput.get(), 'Good old PHP quality profile copy');
       await act(async () => {
-        await user.click(ui.copyDialog.byRole('button', { name: 'copy' }).get());
+        await user.click(ui.dialog.byRole('button', { name: 'copy' }).get());
       });
 
-      expect(ui.copyDialog.query()).not.toBeInTheDocument();
+      expect(ui.dialog.query()).not.toBeInTheDocument();
 
       expect(screen.getAllByText('Good old PHP quality profile copy')).toHaveLength(2);
     });
@@ -327,16 +313,16 @@ describe('Admin or user with permission', () => {
       await user.click(await ui.qualityProfileActions.find());
       await user.click(ui.renameButton.get());
 
-      expect(ui.renameDialog.get()).toBeInTheDocument();
-      expect(ui.renameDialog.byRole('button', { name: 'rename' }).get()).toBeDisabled();
+      expect(ui.dialog.get()).toBeInTheDocument();
+      expect(ui.dialog.byRole('button', { name: 'rename' }).get()).toBeDisabled();
 
       await user.clear(ui.newNameInput.get());
       await user.type(ui.newNameInput.get(), 'Fossil PHP quality profile');
       await act(async () => {
-        await user.click(ui.renameDialog.byRole('button', { name: 'rename' }).get());
+        await user.click(ui.dialog.byRole('button', { name: 'rename' }).get());
       });
 
-      expect(ui.renameDialog.query()).not.toBeInTheDocument();
+      expect(ui.dialog.query()).not.toBeInTheDocument();
 
       expect(screen.getAllByText('Fossil PHP quality profile')).toHaveLength(2);
     });
@@ -366,14 +352,14 @@ describe('Admin or user with permission', () => {
       await user.click(await ui.qualityProfileActions.find());
       await user.click(ui.deleteQualityProfileButton.get());
 
-      expect(ui.deleteProfileDialog.get()).toBeInTheDocument();
+      expect(ui.dialog.get()).toBeInTheDocument();
       expect(
-        ui.deleteProfileDialog
+        ui.dialog
           .byText(/quality_profiles.are_you_sure_want_delete_profile_x_and_descendants/)
           .get()
       ).toBeInTheDocument();
       await act(async () => {
-        await user.click(ui.deleteProfileDialog.byRole('button', { name: 'delete' }).get());
+        await user.click(ui.dialog.byRole('button', { name: 'delete' }).get());
       });
 
       expect(ui.qualityProfilesHeader.get()).toBeInTheDocument();
index 057dff8439ee5e0d78abaa9ad7ca66a83417d473..2366e789002d335c50184be359fc679d80d319bf 100644 (file)
@@ -68,7 +68,7 @@ const ui = {
       name: `quality_profiles.comparison.activate_rule.${profileName}`,
     }),
   activateConfirmButton: byRole('button', { name: 'coding_rules.activate' }),
-  namePropupInput: byRole('textbox', { name: 'quality_profiles.new_name field_required' }),
+  namePropupInput: byRole('textbox', { name: 'quality_profiles.new_name required' }),
   filterByLang: byRole('combobox', { name: 'quality_profiles.filter_by:' }),
   listLinkCQualityProfile: byRole('link', { name: 'c quality profile' }),
   listLinkNewCQualityProfile: byRole('link', { name: 'New c quality profile' }),
index b00ece4ea3f507149fef0f50f5afbc9d7a81b7c7..22e01fec550123b8cc2d73ca52affc1b30a7d056 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+import { ButtonPrimary, FormField, InputField, Modal } from 'design-system';
 import * as React from 'react';
-import Modal from '../../../components/controls/Modal';
-import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
-import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
 import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { Dict } from '../../../types/types';
@@ -42,64 +40,62 @@ const LABELS_FOR_ACTION: Dict<{ button: string; header: string }> = {
 
 export default function ProfileModalForm(props: ProfileModalFormProps) {
   const { action, loading, profile } = props;
-  const [name, setName] = React.useState<string | undefined>(undefined);
+  const [name, setName] = React.useState('');
 
   const submitDisabled = loading || !name || name === profile.name;
   const labels = LABELS_FOR_ACTION[action];
-  const header = translateWithParameters(labels.header, profile.name, profile.languageName);
 
   return (
-    <Modal contentLabel={header} onRequestClose={props.onClose} size="small">
-      <form
-        onSubmit={(e: React.SyntheticEvent<HTMLFormElement>) => {
-          e.preventDefault();
-          if (name) {
-            props.onSubmit(name);
-          }
-        }}
-      >
-        <div className="modal-head">
-          <h2>{header}</h2>
-        </div>
-        <div className="modal-body">
+    <Modal
+      headerTitle={translateWithParameters(labels.header, profile.name, profile.languageName)}
+      onClose={props.onClose}
+      loading={loading}
+      body={
+        <>
           {action === ProfileActionModals.Copy && (
-            <p className="spacer-bottom">
+            <p className="sw-mb-8">
               {translateWithParameters('quality_profiles.copy_help', profile.name)}
             </p>
           )}
           {action === ProfileActionModals.Extend && (
-            <p className="spacer-bottom">
+            <p className="sw-mb-8">
               {translateWithParameters('quality_profiles.extend_help', profile.name)}
             </p>
           )}
 
-          <MandatoryFieldsExplanation className="modal-field" />
-          <div className="modal-field">
-            <label htmlFor="profile-name">
-              {translate('quality_profiles.new_name')}
-              <MandatoryFieldMarker />
-            </label>
-            <input
-              autoFocus
-              id="profile-name"
-              maxLength={100}
+          <MandatoryFieldsExplanation />
+
+          <FormField
+            className="sw-mt-2"
+            htmlFor="quality-profile-new-name"
+            label={translate('quality_profiles.new_name')}
+            required
+          >
+            <InputField
+              id="quality-profile-new-name"
               name="name"
-              onChange={(e: React.SyntheticEvent<HTMLInputElement>) => {
-                setName(e.currentTarget.value);
-              }}
+              onChange={(event) => setName(event.target.value)}
               required
-              size={50}
+              size="full"
               type="text"
-              value={name ?? profile.name}
+              value={name}
             />
-          </div>
-        </div>
-        <div className="modal-foot">
-          {loading && <i className="spinner spacer-right" />}
-          <SubmitButton disabled={submitDisabled}>{translate(labels.button)}</SubmitButton>
-          <ResetButtonLink onClick={props.onClose}>{translate('cancel')}</ResetButtonLink>
-        </div>
-      </form>
-    </Modal>
+          </FormField>
+        </>
+      }
+      primaryButton={
+        <ButtonPrimary
+          onClick={() => {
+            if (name) {
+              props.onSubmit(name);
+            }
+          }}
+          disabled={submitDisabled}
+        >
+          {translate(labels.button)}
+        </ButtonPrimary>
+      }
+      secondaryButtonLabel={translate('cancel')}
+    />
   );
 }