]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16087 Remove select legacy from permissions, projectActivity and projectBaseline
authorRevanshu Paliwal <revanshu.paliwal@sonarsource.com>
Tue, 29 Mar 2022 10:05:31 +0000 (12:05 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 30 Mar 2022 13:38:10 +0000 (13:38 +0000)
server/sonar-web/src/main/js/apps/permissions/project/components/ApplyTemplate.tsx
server/sonar-web/src/main/js/apps/permissions/project/components/__tests__/ApplyTemplate-test.tsx
server/sonar-web/src/main/js/apps/permissions/project/components/__tests__/__snapshots__/ApplyTemplate-test.tsx.snap
server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityEventSelectOption.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.tsx
server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityEventSelectOption-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityEventSelectOption-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageHeader-test.tsx.snap
server/sonar-web/src/main/js/apps/projectBaseline/components/BranchAnalysisListRenderer.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchAnalysisListRenderer-test.tsx.snap

index 2c4fbe85e98c4a9bafb4628fe4be0a248b95e9c8..2cf7d042a1a63034415e6254c8049556442fc525 100644 (file)
@@ -18,9 +18,9 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
+import Select from '../../../../components/controls/Select';
 import { applyTemplateToProject, getPermissionTemplates } from '../../../../api/permissions';
 import { ResetButtonLink, SubmitButton } from '../../../../components/controls/buttons';
-import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import SimpleModal from '../../../../components/controls/SimpleModal';
 import { Alert } from '../../../../components/ui/Alert';
 import DeferredSpinner from '../../../../components/ui/DeferredSpinner';
@@ -28,6 +28,7 @@ import MandatoryFieldMarker from '../../../../components/ui/MandatoryFieldMarker
 import MandatoryFieldsExplanation from '../../../../components/ui/MandatoryFieldsExplanation';
 import { translate, translateWithParameters } from '../../../../helpers/l10n';
 import { PermissionTemplate } from '../../../../types/types';
+import { components, OptionProps } from 'react-select';
 
 interface Props {
   onApply?: () => void;
@@ -55,6 +56,11 @@ export default class ApplyTemplate extends React.PureComponent<Props, State> {
     this.mounted = false;
   }
 
+  optionRenderer = (props: OptionProps<{ value: string }, false>) => (
+    // This class is added for the integration test.
+    <components.Option {...props} className="Select-option" />
+  );
+
   fetchPermissionTemplates = () => {
     getPermissionTemplates().then(
       ({ permissionTemplates }) => {
@@ -98,6 +104,13 @@ export default class ApplyTemplate extends React.PureComponent<Props, State> {
       this.props.project.name
     );
 
+    const options = this.state.permissionTemplates
+      ? this.state.permissionTemplates.map(permissionTemplate => ({
+          label: permissionTemplate.name,
+          value: permissionTemplate.id
+        }))
+      : [];
+
     return (
       <SimpleModal
         header={header}
@@ -121,20 +134,21 @@ export default class ApplyTemplate extends React.PureComponent<Props, State> {
                 <>
                   <MandatoryFieldsExplanation className="modal-field" />
                   <div className="modal-field">
-                    <label htmlFor="project-permissions-template">
+                    <label htmlFor="project-permissions-template-input">
                       {translate('template')}
                       <MandatoryFieldMarker />
                     </label>
                     {this.state.permissionTemplates && (
-                      <SelectLegacy
-                        clearable={false}
+                      <Select
                         id="project-permissions-template"
+                        className="Select"
+                        inputId="project-permissions-template-input"
                         onChange={this.handlePermissionTemplateChange}
-                        options={this.state.permissionTemplates.map(permissionTemplate => ({
-                          label: permissionTemplate.name,
-                          value: permissionTemplate.id
-                        }))}
-                        value={this.state.permissionTemplate}
+                        components={{
+                          Option: this.optionRenderer
+                        }}
+                        options={options}
+                        value={options.filter(o => o.value === this.state.permissionTemplate)}
                       />
                     )}
                   </div>
index 65edfd756ba2bdb34d9e9d57dd7232cc918b16c1..d40525860c5d72e4454cf63b6b8cccfa8f750238 100644 (file)
@@ -19,6 +19,7 @@
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
+import { mockReactSelectOptionProps } from '../../../../../helpers/mocks/react-select';
 import { waitAndUpdate } from '../../../../../helpers/testUtils';
 import ApplyTemplate from '../ApplyTemplate';
 
@@ -51,3 +52,13 @@ it('render correctly', async () => {
   await waitAndUpdate(wrapper);
   expect(wrapper.dive()).toMatchSnapshot();
 });
+
+it('should render option correctly', () => {
+  const wrapper = shallow<ApplyTemplate>(
+    <ApplyTemplate onClose={jest.fn()} project={{ key: 'foo', name: 'Foo' }} />
+  );
+  const OptionRendererer = wrapper.instance().optionRenderer;
+  expect(
+    shallow(<OptionRendererer {...mockReactSelectOptionProps({ value: 'val' })} />)
+  ).toMatchSnapshot('option renderer');
+});
index 36de38354e61ecced6cc19eb0eda672c47244b4b..0ceb14c48828c4a028594401b95376c993ffb232 100644 (file)
@@ -38,14 +38,20 @@ exports[`render correctly 2`] = `
         className="modal-field"
       >
         <label
-          htmlFor="project-permissions-template"
+          htmlFor="project-permissions-template-input"
         >
           template
           <MandatoryFieldMarker />
         </label>
-        <SelectLegacy
-          clearable={false}
+        <Select
+          className="Select"
+          components={
+            Object {
+              "Option": [Function],
+            }
+          }
           id="project-permissions-template"
+          inputId="project-permissions-template-input"
           onChange={[Function]}
           options={
             Array [
@@ -55,6 +61,7 @@ exports[`render correctly 2`] = `
               },
             ]
           }
+          value={Array []}
         />
       </div>
     </div>
@@ -79,3 +86,14 @@ exports[`render correctly 2`] = `
   </form>
 </Modal>
 `;
+
+exports[`should render option correctly: option renderer 1`] = `
+<Option
+  className="Select-option"
+  data={
+    Object {
+      "value": "val",
+    }
+  }
+/>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityEventSelectOption.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityEventSelectOption.tsx
deleted file mode 100644 (file)
index 2575ebf..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 * as React from 'react';
-
-export interface Option {
-  label: string;
-  value: string;
-}
-
-interface Props {
-  option: Option;
-  children?: Element | Text;
-  className?: string;
-  isFocused?: boolean;
-  onFocus: (option: Option, event: React.MouseEvent<HTMLDivElement>) => void;
-  onSelect: (option: Option, event: React.MouseEvent<HTMLDivElement>) => void;
-}
-
-export default class ProjectActivityEventSelectOption extends React.PureComponent<Props> {
-  handleMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {
-    event.preventDefault();
-    event.stopPropagation();
-    this.props.onSelect(this.props.option, event);
-  };
-
-  handleMouseEnter = (event: React.MouseEvent<HTMLDivElement>) => {
-    this.props.onFocus(this.props.option, event);
-  };
-
-  handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {
-    if (this.props.isFocused) {
-      return;
-    }
-    this.props.onFocus(this.props.option, event);
-  };
-
-  render() {
-    const { option } = this.props;
-    return (
-      <div
-        className={this.props.className}
-        onMouseDown={this.handleMouseDown}
-        onMouseEnter={this.handleMouseEnter}
-        onMouseMove={this.handleMouseMove}
-        role="link"
-        tabIndex={0}
-        title={option.label}>
-        {this.props.children}
-      </div>
-    );
-  }
-}
index bd84ec6f4243ee5b4e74206b0ce986ff3731d748..57f22d992982021736c79d6ddd010c27d6eb82a2 100644 (file)
  */
 import classNames from 'classnames';
 import * as React from 'react';
-import SelectLegacy from '../../../components/controls/SelectLegacy';
+import Select from '../../../components/controls/Select';
 import { translate } from '../../../helpers/l10n';
 import { Component } from '../../../types/types';
 import { APPLICATION_EVENT_TYPES, EVENT_TYPES, Query } from '../utils';
 import ProjectActivityDateInput from './ProjectActivityDateInput';
-import ProjectActivityEventSelectOption from './ProjectActivityEventSelectOption';
 
 interface Props {
   category?: string;
@@ -49,18 +48,17 @@ export default class ProjectActivityPageHeader extends React.PureComponent<Props
     return (
       <header className="page-header">
         {!['VW', 'SVW'].includes(this.props.project.qualifier) && (
-          <SelectLegacy
+          <Select
             className={classNames('pull-left big-spacer-right', {
               'input-medium': !isApp,
               'input-large': isApp
             })}
-            clearable={true}
+            placeholder={translate('project_activity.filter_events') + '...'}
+            isClearable={true}
+            isSearchable={false}
             onChange={this.handleCategoryChange}
-            optionComponent={ProjectActivityEventSelectOption}
             options={options}
-            placeholder={translate('project_activity.filter_events') + '...'}
-            searchable={false}
-            value={this.props.category}
+            value={options.filter(o => o.value === this.props.category)}
           />
         )}
         <ProjectActivityDateInput
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityEventSelectOption-test.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityEventSelectOption-test.tsx
deleted file mode 100644 (file)
index b4142c8..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import ProjectActivityEventSelectOption from '../ProjectActivityEventSelectOption';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<ProjectActivityEventSelectOption['props']> = {}) {
-  return shallow(
-    <ProjectActivityEventSelectOption
-      onFocus={jest.fn()}
-      onSelect={jest.fn()}
-      option={{ label: 'Foo', value: 'foo' }}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityEventSelectOption-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityEventSelectOption-test.tsx.snap
deleted file mode 100644 (file)
index 9667ac4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<div
-  onMouseDown={[Function]}
-  onMouseEnter={[Function]}
-  onMouseMove={[Function]}
-  role="link"
-  tabIndex={0}
-  title="Foo"
-/>
-`;
index 17cf32889251eaaabd4e8b2bafc13ac17f7f7cb9..5659e62e4512ee77f28cc1a2c32274e475c19992 100644 (file)
@@ -4,11 +4,11 @@ exports[`should render correctly the list of series 1`] = `
 <header
   className="page-header"
 >
-  <SelectLegacy
+  <Select
     className="pull-left big-spacer-right input-medium"
-    clearable={true}
+    isClearable={true}
+    isSearchable={false}
     onChange={[Function]}
-    optionComponent={[Function]}
     options={
       Array [
         Object {
@@ -30,8 +30,7 @@ exports[`should render correctly the list of series 1`] = `
       ]
     }
     placeholder="project_activity.filter_events..."
-    searchable={false}
-    value=""
+    value={Array []}
   />
   <ProjectActivityDateInput
     from={2016-10-27T10:21:15.000Z}
index 93e3f2d2f83dbb31b0e2bd71d3a872c2b91e6bf0..b9031a25063edce25d8a7181b8779b6a5b8bf75f 100644 (file)
@@ -19,8 +19,8 @@
  */
 import classNames from 'classnames';
 import * as React from 'react';
+import Select from '../../../components/controls/Select';
 import Radio from '../../../components/controls/Radio';
-import SelectLegacy from '../../../components/controls/SelectLegacy';
 import Tooltip from '../../../components/controls/Tooltip';
 import DateFormatter from '../../../components/intl/DateFormatter';
 import TimeFormatter from '../../../components/intl/TimeFormatter';
@@ -95,27 +95,31 @@ export default function BranchAnalysisListRenderer(props: BranchAnalysisListRend
     byVersionByDay.length > 1 ||
     (byVersionByDay.length === 1 && Object.keys(byVersionByDay[0].byDay).length > 0);
 
+  const options = [
+    {
+      label: translate('baseline.branch_analyses.ranges.30days'),
+      value: 30
+    },
+    {
+      label: translate('baseline.branch_analyses.ranges.allTime'),
+      value: 0
+    }
+  ];
+
   return (
     <>
       <div className="spacer-bottom">
-        {translate('baseline.analysis_from')}
-        <SelectLegacy
+        <label htmlFor="branch-analysis-from-input" className="spacer-right">
+          {translate('baseline.analysis_from')}
+        </label>
+        <Select
           autoBlur={true}
+          inputId="branch-analysis-from-input"
           className="input-medium spacer-left"
-          clearable={false}
           onChange={props.handleRangeChange}
-          options={[
-            {
-              label: translate('baseline.branch_analyses.ranges.30days'),
-              value: 30
-            },
-            {
-              label: translate('baseline.branch_analyses.ranges.allTime'),
-              value: 0
-            }
-          ]}
-          searchable={false}
-          value={range}
+          options={options}
+          isSearchable={false}
+          value={options.filter(o => o.value === range)}
         />
       </div>
       <div className="branch-analysis-list-wrapper">
index 44f7ba92bbc4cad6b10fb57787ebfee71ccfbad8..fff6d543a90b275f5661a925aece73701a57e537 100644 (file)
@@ -5,11 +5,17 @@ exports[`should render correctly: Analyses 1`] = `
   <div
     className="spacer-bottom"
   >
-    baseline.analysis_from
-    <SelectLegacy
+    <label
+      className="spacer-right"
+      htmlFor="branch-analysis-from-input"
+    >
+      baseline.analysis_from
+    </label>
+    <Select
       autoBlur={true}
       className="input-medium spacer-left"
-      clearable={false}
+      inputId="branch-analysis-from-input"
+      isSearchable={false}
       onChange={[MockFunction]}
       options={
         Array [
@@ -23,8 +29,14 @@ exports[`should render correctly: Analyses 1`] = `
           },
         ]
       }
-      searchable={false}
-      value={30}
+      value={
+        Array [
+          Object {
+            "label": "baseline.branch_analyses.ranges.30days",
+            "value": 30,
+          },
+        ]
+      }
     />
   </div>
   <div
@@ -301,11 +313,17 @@ exports[`should render correctly: empty 1`] = `
   <div
     className="spacer-bottom"
   >
-    baseline.analysis_from
-    <SelectLegacy
+    <label
+      className="spacer-right"
+      htmlFor="branch-analysis-from-input"
+    >
+      baseline.analysis_from
+    </label>
+    <Select
       autoBlur={true}
       className="input-medium spacer-left"
-      clearable={false}
+      inputId="branch-analysis-from-input"
+      isSearchable={false}
       onChange={[MockFunction]}
       options={
         Array [
@@ -319,8 +337,14 @@ exports[`should render correctly: empty 1`] = `
           },
         ]
       }
-      searchable={false}
-      value={30}
+      value={
+        Array [
+          Object {
+            "label": "baseline.branch_analyses.ranges.30days",
+            "value": 30,
+          },
+        ]
+      }
     />
   </div>
   <div
@@ -345,11 +369,17 @@ exports[`should render correctly: loading 1`] = `
   <div
     className="spacer-bottom"
   >
-    baseline.analysis_from
-    <SelectLegacy
+    <label
+      className="spacer-right"
+      htmlFor="branch-analysis-from-input"
+    >
+      baseline.analysis_from
+    </label>
+    <Select
       autoBlur={true}
       className="input-medium spacer-left"
-      clearable={false}
+      inputId="branch-analysis-from-input"
+      isSearchable={false}
       onChange={[MockFunction]}
       options={
         Array [
@@ -363,8 +393,14 @@ exports[`should render correctly: loading 1`] = `
           },
         ]
       }
-      searchable={false}
-      value={30}
+      value={
+        Array [
+          Object {
+            "label": "baseline.branch_analyses.ranges.30days",
+            "value": 30,
+          },
+        ]
+      }
     />
   </div>
   <div