]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15655 Change Project perspective and sorting to use react-select@v5
authorMathieu Suen <mathieu.suen@sonarsource.com>
Wed, 17 Nov 2021 16:06:55 +0000 (17:06 +0100)
committersonartech <sonartech@sonarsource.com>
Fri, 26 Nov 2021 20:03:18 +0000 (20:03 +0000)
105 files changed:
server/sonar-web/package.json
server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts
server/sonar-web/src/main/js/app/components/nav/component/projectInformation/badges/BadgeParams.tsx
server/sonar-web/src/main/js/app/components/nav/component/projectInformation/badges/__tests__/__snapshots__/BadgeParams-test.tsx.snap
server/sonar-web/src/main/js/apps/application-console/ProjectBranchRow.tsx
server/sonar-web/src/main/js/apps/application-console/__tests__/__snapshots__/ProjectBranchRow-test.tsx.snap
server/sonar-web/src/main/js/apps/application-settings/ReportFrequencyForm.tsx
server/sonar-web/src/main/js/apps/application-settings/__tests__/ReportFrequencyForm-test.tsx
server/sonar-web/src/main/js/apps/application-settings/__tests__/__snapshots__/ReportFrequencyForm-test.tsx.snap
server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/WorkersForm.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.tsx.snap
server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
server/sonar-web/src/main/js/apps/coding-rules/components/BulkChangeModal.tsx
server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/BulkChangeModal-test.tsx.snap
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap
server/sonar-web/src/main/js/apps/component-measures/components/MeasureViewSelect.tsx
server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/MeasureViewSelect-test.tsx.snap
server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx
server/sonar-web/src/main/js/apps/issues/components/__tests__/BulkChangeModal-test.tsx
server/sonar-web/src/main/js/apps/permissions/project/components/ApplyTemplate.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/ProjectActivityPageHeader.tsx
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
server/sonar-web/src/main/js/apps/projectQualityGate/ProjectQualityGateAppRenderer.tsx
server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/ProjectQualityGateAppRenderer-test.tsx
server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/ProjectQualityGateAppRenderer-test.tsx.snap
server/sonar-web/src/main/js/apps/projectQualityProfiles/components/AddLanguageModal.tsx
server/sonar-web/src/main/js/apps/projectQualityProfiles/components/SetQualityProfileModal.tsx
server/sonar-web/src/main/js/apps/projectQualityProfiles/components/__tests__/AddLanguageModal-test.tsx
server/sonar-web/src/main/js/apps/projectQualityProfiles/components/__tests__/SetQualityProfileModal-test.tsx
server/sonar-web/src/main/js/apps/projectQualityProfiles/components/__tests__/__snapshots__/AddLanguageModal-test.tsx.snap
server/sonar-web/src/main/js/apps/projectQualityProfiles/components/__tests__/__snapshots__/SetQualityProfileModal-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelect.tsx
server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelectOption.tsx [deleted file]
server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelect.tsx
server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelectOption.tsx [deleted file]
server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelect-test.tsx
server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelectOption-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelect-test.tsx
server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelectOption-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelectOption-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelect-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelectOption-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterFooter.tsx
server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchableFilterFooter-test.tsx
server/sonar-web/src/main/js/apps/projectsManagement/BulkApplyTemplateModal.tsx
server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Search-test.tsx
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/BulkApplyTemplateModal-test.tsx.snap
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/Search-test.tsx.snap
server/sonar-web/src/main/js/apps/quality-gates/components/ConditionOperator.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/MetricSelect.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatePermissionsAddModalRenderer.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/QualityGatePermissionsAddModalRenderer-test.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/ConditionOperator-test.tsx.snap
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/MetricSelect-test.tsx.snap
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/QualityGatePermissionsAddModalRenderer-test.tsx.snap
server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx
server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.tsx
server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx
server/sonar-web/src/main/js/apps/quality-profiles/details/ProfilePermissionsFormSelect.tsx
server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ChangeParentForm-test.tsx.snap
server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfilePermissionsFormSelect-test.tsx.snap
server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx
server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.tsx
server/sonar-web/src/main/js/apps/quality-profiles/home/__tests__/__snapshots__/CreateProfileForm-test.tsx.snap
server/sonar-web/src/main/js/apps/quality-profiles/home/__tests__/__snapshots__/ProfilesListHeader-test.tsx.snap
server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/FilterBar-test.tsx.snap
server/sonar-web/src/main/js/apps/settings/components/Languages.tsx
server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx
server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap
server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.tsx
server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.tsx
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap
server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.tsx
server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearch-test.tsx.snap
server/sonar-web/src/main/js/components/activity-graph/GraphsHeader.tsx
server/sonar-web/src/main/js/components/controls/DateInput.tsx
server/sonar-web/src/main/js/components/controls/SearchSelect.tsx
server/sonar-web/src/main/js/components/controls/Select.css [deleted file]
server/sonar-web/src/main/js/components/controls/Select.tsx
server/sonar-web/src/main/js/components/controls/SelectLegacy.css [new file with mode: 0644]
server/sonar-web/src/main/js/components/controls/SelectLegacy.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/controls/__tests__/Select-test.tsx
server/sonar-web/src/main/js/components/controls/__tests__/SelectLegacy-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchSelect-test.tsx.snap
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Select-test.tsx.snap
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectLegacy-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/mocks/react-select.ts [new file with mode: 0644]
server/sonar-web/yarn.lock

index afdd07e8e0675468bd3b918cd41c2777a8ce33d0..86ff408abfae1f7fb1d74ae0214517f0e4d38ebc 100644 (file)
@@ -37,7 +37,8 @@
     "react-modal": "3.14.3",
     "react-redux": "5.1.1",
     "react-router": "3.2.6",
-    "react-select": "1.2.1",
+    "react-select": "4.3.1",
+    "react-select-legacy": "npm:react-select@1.2.1",
     "react-virtualized": "9.21.2",
     "redux": "4.0.5",
     "redux-thunk": "2.3.0",
@@ -80,7 +81,8 @@
     "@types/react-modal": "3.12.1",
     "@types/react-redux": "6.0.6",
     "@types/react-router": "3.0.20",
-    "@types/react-select": "1.2.6",
+    "@types/react-select": "4.0.16",
+    "@types/react-select-legacy": "npm:@types/react-select@1.2.6",
     "@types/react-virtualized": "9.21.0",
     "@types/sanitize-html": "1.22.0",
     "@types/valid-url": "1.0.2",
index efa37b2a77a4ef83a1f56db7be3a6bfbf0cbb637..6ccff0a0c571f24208c25e0b7f2ff19a211ac6c0 100644 (file)
@@ -40,7 +40,7 @@ import RadioToggle from '../../../components/controls/RadioToggle';
 import ReloadButton from '../../../components/controls/ReloadButton';
 import SearchBox from '../../../components/controls/SearchBox';
 import SearchSelect from '../../../components/controls/SearchSelect';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import SelectList, { SelectListFilter } from '../../../components/controls/SelectList';
 import SimpleModal from '../../../components/controls/SimpleModal';
 import Tooltip from '../../../components/controls/Tooltip';
@@ -219,7 +219,7 @@ const exposeLibraries = () => {
         SearchBox,
         SearchSelect,
         SecurityHotspotIcon,
-        Select,
+        SelectLegacy,
         SelectList,
         SelectListFilter,
         SimpleModal,
index 92a8e74dbb2e834339ce3016ec80d9555819d158..0327f91c6368e450646785068e9617ed929f1a8a 100644 (file)
@@ -20,7 +20,7 @@
 import classNames from 'classnames';
 import * as React from 'react';
 import { fetchWebApi } from '../../../../../../api/web-api';
-import Select from '../../../../../../components/controls/Select';
+import SelectLegacy from '../../../../../../components/controls/SelectLegacy';
 import { getLocalizedMetricName, translate } from '../../../../../../helpers/l10n';
 import { BadgeFormats, BadgeOptions, BadgeType } from './utils';
 
@@ -105,7 +105,7 @@ export default class BadgeParams extends React.PureComponent<Props> {
           <label className="spacer-right" htmlFor="badge-metric">
             {translate('overview.badges.metric')}:
           </label>
-          <Select
+          <SelectLegacy
             className="input-medium"
             clearable={false}
             menuStyle={{ maxHeight: 100 }}
@@ -135,7 +135,7 @@ export default class BadgeParams extends React.PureComponent<Props> {
           htmlFor="badge-format">
           {translate('format')}:
         </label>
-        <Select
+        <SelectLegacy
           className="input-medium"
           clearable={false}
           name="badge-format"
index 704be60fbcce9d1cdb3f1dac4cf3bf453aef8eaa..a9a46bf033aae86710bd8a2de320a99aedb02bb2 100644 (file)
@@ -9,7 +9,7 @@ exports[`should display measure badge params 1`] = `
     overview.badges.metric
     :
   </label>
-  <Select
+  <SelectLegacy
     className="input-medium"
     clearable={false}
     menuStyle={
@@ -30,7 +30,7 @@ exports[`should display measure badge params 1`] = `
     format
     :
   </label>
-  <Select
+  <SelectLegacy
     className="input-medium"
     clearable={false}
     name="badge-format"
@@ -62,7 +62,7 @@ exports[`should display quality gate badge params 1`] = `
     format
     :
   </label>
-  <Select
+  <SelectLegacy
     className="input-medium"
     clearable={false}
     name="badge-format"
index 746b1fb76098dc330ee7763b08c8de6bac7b2e95..936859b7cad3968c87e4df3fdb7c0283a3083fe6 100644 (file)
@@ -21,7 +21,7 @@ import { orderBy } from 'lodash';
 import * as React from 'react';
 import { getBranches } from '../../api/branches';
 import Checkbox from '../../components/controls/Checkbox';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
 import Tooltip from '../../components/controls/Tooltip';
 import QualifierIcon from '../../components/icons/QualifierIcon';
 import DeferredSpinner from '../../components/ui/DeferredSpinner';
@@ -117,7 +117,7 @@ export default class ProjectBranchRow extends React.PureComponent<Props, State>
           </Tooltip>
         </td>
         <td>
-          <Select
+          <SelectLegacy
             className="width100"
             clearable={false}
             disabled={!checked}
index b2a8af392e0894cd3c70c5f0047a3bba43285ebb..26bfbcbc76ca9db79e0423e875446f18ed6483e9 100644 (file)
@@ -30,7 +30,7 @@ exports[`Should render correctly 1`] = `
     </Tooltip>
   </td>
   <td>
-    <Select
+    <SelectLegacy
       className="width100"
       clearable={false}
       disabled={false}
index b2384ab7908e2bddec1ac73418a1888c305961f8..545d432c459017006b4630e4c79c19d7d470d4b0 100644 (file)
@@ -19,7 +19,7 @@
  */
 import * as React from 'react';
 import { Button, ResetButtonLink } from '../../components/controls/buttons';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
 import { translate } from '../../helpers/l10n';
 import { sanitizeStringRestricted } from '../../helpers/sanitize';
 import { SettingCategoryDefinition } from '../../types/settings';
@@ -61,7 +61,7 @@ export default function ReportFrequencyForm(props: ReportFrequencyFormProps) {
         />
       )}
 
-      <Select
+      <SelectLegacy
         className="input-medium"
         clearable={false}
         name={definition.name}
index 7d91a1bf6ec5615fa134ab012c980666f386bcd1..dc6db927c59a28dca2651a3144ba77dd186a7b32 100644 (file)
@@ -20,7 +20,7 @@
 import { shallow } from 'enzyme';
 import * as React from 'react';
 import { Button, ResetButtonLink } from '../../../components/controls/buttons';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { mockDefinition } from '../../../helpers/mocks/settings';
 import ReportFrequencyForm, { ReportFrequencyFormProps } from '../ReportFrequencyForm';
 
@@ -34,7 +34,7 @@ it('should handle changes', () => {
   const onSave = jest.fn();
   const wrapper = shallowRender({ onSave });
 
-  wrapper.find(Select).simulate('change', { value: 'Daily' });
+  wrapper.find(SelectLegacy).simulate('change', { value: 'Daily' });
 
   expect(wrapper.find('.button-success').exists()).toBe(true);
   expect(wrapper.find(ResetButtonLink).exists()).toBe(true);
index dc8322658c5be2b3126c69f6230b712dbfef6482..7ea031a392baef3e56cf805805f1c284b0cc61d2 100644 (file)
@@ -13,7 +13,7 @@ exports[`should render correctly: changed 1`] = `
       }
     }
   />
-  <Select
+  <SelectLegacy
     className="input-medium"
     clearable={false}
     onChange={[Function]}
@@ -61,7 +61,7 @@ exports[`should render correctly: default 1`] = `
       }
     }
   />
-  <Select
+  <SelectLegacy
     className="input-medium"
     clearable={false}
     onChange={[Function]}
@@ -94,7 +94,7 @@ exports[`should render correctly: no description 1`] = `
   <h2>
     application_settings.report.frequency
   </h2>
-  <Select
+  <SelectLegacy
     className="input-medium"
     clearable={false}
     onChange={[Function]}
index 3559243ffab31e212c4414fc81874d072362538a..030a65b86ec9e164e4baa8834eb76e671824f97e 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { translate } from '../../../helpers/l10n';
 import { TaskStatuses } from '../../../types/tasks';
 import { STATUSES } from '../constants';
@@ -48,7 +48,7 @@ export default class StatusFilter extends React.PureComponent<Props> {
     ];
 
     return (
-      <Select
+      <SelectLegacy
         className="input-medium"
         clearable={false}
         onChange={this.handleChange}
index a2537b03b63de391fd23f59b11ef612ece95f30b..c366dea59a7b106913263d17b5086c553f429e5e 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { translate } from '../../../helpers/l10n';
 import { ALL_TYPES } from '../constants';
 
@@ -48,7 +48,7 @@ export default class TypesFilter extends React.PureComponent<Props> {
     ];
 
     return (
-      <Select
+      <SelectLegacy
         className="input-large"
         clearable={false}
         onChange={this.handleChange}
index 0264513dd33b821c47da180a7700303b51a1062f..ba0b868693f4cbfa98429bc6a0717ad1b646ac56 100644 (file)
@@ -21,7 +21,7 @@ import * as React from 'react';
 import { setWorkerCount } from '../../../api/ce';
 import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
 import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { Alert } from '../../../components/ui/Alert';
 import { translate } from '../../../helpers/l10n';
 
@@ -96,7 +96,7 @@ export default class WorkersForm extends React.PureComponent<Props, State> {
         </header>
         <form onSubmit={this.handleSubmit}>
           <div className="modal-body">
-            <Select
+            <SelectLegacy
               className="input-tiny spacer-top"
               clearable={false}
               onChange={this.handleWorkerCountChange}
index 3e6d8f3737b85a0fd20d4b8afb3b05a6f8be8a52..0e2813ac0f3484d44d06bc3bfe90f0c0726ffae7 100644 (file)
@@ -24,6 +24,7 @@ jest.mock('../../../../api/ce', () => ({
 
 import { shallow } from 'enzyme';
 import * as React from 'react';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import { submit } from '../../../../helpers/testUtils';
 import WorkersForm from '../WorkersForm';
 
@@ -31,7 +32,7 @@ it('changes select', () => {
   const wrapper = shallow(<WorkersForm onClose={jest.fn()} workerCount={1} />);
   expect(wrapper).toMatchSnapshot();
 
-  wrapper.find('Select').prop<Function>('onChange')({ value: 7 });
+  wrapper.find(SelectLegacy).prop<Function>('onChange')({ value: 7 });
   wrapper.update();
   expect(wrapper).toMatchSnapshot();
 });
@@ -40,7 +41,7 @@ it('returns new worker count', async () => {
   const onClose = jest.fn();
   const wrapper = shallow(<WorkersForm onClose={onClose} workerCount={1} />);
   (wrapper.instance() as WorkersForm).mounted = true;
-  wrapper.find('Select').prop<Function>('onChange')({ value: 7 });
+  wrapper.find(SelectLegacy).prop<Function>('onChange')({ value: 7 });
 
   wrapper.update();
   submit(wrapper.find('form'));
index 527175beff335abc91884742eadd28d9fa31b4f6..da66d6be96bb4aee6f693e2f198be79275a8c30c 100644 (file)
@@ -18,7 +18,7 @@ exports[`changes select 1`] = `
     <div
       className="modal-body"
     >
-      <Select
+      <SelectLegacy
         className="input-tiny spacer-top"
         clearable={false}
         onChange={[Function]}
@@ -114,7 +114,7 @@ exports[`changes select 2`] = `
     <div
       className="modal-body"
     >
-      <Select
+      <SelectLegacy
         className="input-tiny spacer-top"
         clearable={false}
         onChange={[Function]}
index 7ce6bdf12c63a259179f6795236ac6cf02dda0e9..dd4a680feb01e48b666da0d7c5d424018f4a2cde 100644 (file)
@@ -22,7 +22,7 @@ import * as React from 'react';
 import { activateRule, Profile } from '../../../api/quality-profiles';
 import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
 import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import SeverityHelper from '../../../components/shared/SeverityHelper';
 import { Alert } from '../../../components/ui/Alert';
 import { SEVERITIES } from '../../../helpers/constants';
@@ -166,7 +166,7 @@ export default class ActivationFormModal extends React.PureComponent<Props, Stat
 
             <div className="modal-field">
               <label>{translate('coding_rules.quality_profile')}</label>
-              <Select
+              <SelectLegacy
                 className="js-profile"
                 clearable={false}
                 disabled={submitting || profilesWithDepth.length === 1}
@@ -180,7 +180,7 @@ export default class ActivationFormModal extends React.PureComponent<Props, Stat
             </div>
             <div className="modal-field">
               <label>{translate('severity')}</label>
-              <Select
+              <SelectLegacy
                 className="js-severity"
                 clearable={false}
                 disabled={submitting}
index b1c8f2e422ed29971408b2bbb1a82c1cb3397f8b..bb853cf92c57e6c1edff06208612a6190bf638f9 100644 (file)
@@ -21,7 +21,7 @@ import * as React from 'react';
 import { bulkActivateRules, bulkDeactivateRules, Profile } from '../../../api/quality-profiles';
 import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
 import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { Alert } from '../../../components/ui/Alert';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { formatMeasure } from '../../../helpers/measures';
@@ -182,7 +182,7 @@ export default class BulkChangeModal extends React.PureComponent<Props, State> {
       value: profile.key
     }));
     return (
-      <Select
+      <SelectLegacy
         multi={true}
         onChange={this.handleProfileSelect}
         options={options}
index 68b675fb99ddcc47aeb8d3828efa56c35a5173b1..25fcb3c8e604de4d528dc2eabc21b27176f1f912 100644 (file)
@@ -22,7 +22,7 @@ import { createRule, updateRule } from '../../../api/rules';
 import FormattingTips from '../../../components/common/FormattingTips';
 import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
 import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import SeverityHelper from '../../../components/shared/SeverityHelper';
 import TypeHelper from '../../../components/shared/TypeHelper';
 import { Alert } from '../../../components/ui/Alert';
@@ -218,7 +218,7 @@ export default class CustomRuleFormModal extends React.PureComponent<Props, Stat
   renderTypeField = () => (
     <div className="modal-field flex-1 spacer-right">
       <label htmlFor="coding-rules-custom-rule-type">{translate('type')}</label>
-      <Select
+      <SelectLegacy
         clearable={false}
         disabled={this.state.submitting}
         id="coding-rules-custom-rule-type"
@@ -240,7 +240,7 @@ export default class CustomRuleFormModal extends React.PureComponent<Props, Stat
   renderSeverityField = () => (
     <div className="modal-field flex-1 spacer-right">
       <label htmlFor="coding-rules-custom-rule-severity">{translate('severity')}</label>
-      <Select
+      <SelectLegacy
         clearable={false}
         disabled={this.state.submitting}
         id="coding-rules-custom-rule-severity"
@@ -262,7 +262,7 @@ export default class CustomRuleFormModal extends React.PureComponent<Props, Stat
       <label htmlFor="coding-rules-custom-rule-status">
         {translate('coding_rules.filters.status')}
       </label>
-      <Select
+      <SelectLegacy
         clearable={false}
         disabled={this.state.submitting}
         id="coding-rules-custom-rule-status"
index 2adb2cf8b78995a8c327a606ce74d1c21d77c266..772f62dee6b4a31a252780500964cc5cabd1570d 100644 (file)
@@ -30,7 +30,7 @@ exports[`should render correctly: custom rule 1`] = `
         <label>
           coding_rules.quality_profile
         </label>
-        <Select
+        <SelectLegacy
           className="js-profile"
           clearable={false}
           disabled={false}
@@ -45,7 +45,7 @@ exports[`should render correctly: custom rule 1`] = `
         <label>
           severity
         </label>
-        <Select
+        <SelectLegacy
           className="js-severity"
           clearable={false}
           disabled={false}
@@ -139,7 +139,7 @@ exports[`should render correctly: default 1`] = `
         <label>
           coding_rules.quality_profile
         </label>
-        <Select
+        <SelectLegacy
           className="js-profile"
           clearable={false}
           disabled={false}
@@ -154,7 +154,7 @@ exports[`should render correctly: default 1`] = `
         <label>
           severity
         </label>
-        <Select
+        <SelectLegacy
           className="js-severity"
           clearable={false}
           disabled={false}
@@ -283,7 +283,7 @@ exports[`should render correctly: submitting 1`] = `
         <label>
           coding_rules.quality_profile
         </label>
-        <Select
+        <SelectLegacy
           className="js-profile"
           clearable={false}
           disabled={true}
@@ -298,7 +298,7 @@ exports[`should render correctly: submitting 1`] = `
         <label>
           severity
         </label>
-        <Select
+        <SelectLegacy
           className="js-severity"
           clearable={false}
           disabled={true}
@@ -425,7 +425,7 @@ exports[`should render correctly: update mode 1`] = `
         <label>
           coding_rules.quality_profile
         </label>
-        <Select
+        <SelectLegacy
           className="js-profile"
           clearable={false}
           disabled={false}
@@ -440,7 +440,7 @@ exports[`should render correctly: update mode 1`] = `
         <label>
           severity
         </label>
-        <Select
+        <SelectLegacy
           className="js-severity"
           clearable={false}
           disabled={false}
@@ -564,7 +564,7 @@ exports[`should render correctly: with deep profiles 1`] = `
         <label>
           coding_rules.quality_profile
         </label>
-        <Select
+        <SelectLegacy
           className="js-profile"
           clearable={false}
           disabled={true}
@@ -586,7 +586,7 @@ exports[`should render correctly: with deep profiles 1`] = `
         <label>
           severity
         </label>
-        <Select
+        <SelectLegacy
           className="js-severity"
           clearable={false}
           disabled={false}
index 3dfb406d2a07d1a49e79bd3b10ba4c746f7be429..cef2f30066b9639c6819142ce5e5e45b90a714a6 100644 (file)
@@ -171,7 +171,7 @@ exports[`should render correctly: no profile pre-selected 1`] = `
             coding_rules.activate_in
           </label>
         </h3>
-        <Select
+        <SelectLegacy
           multi={true}
           onChange={[Function]}
           options={Array []}
index 3aed94f5b25e572806541510bd4c6e374b9b6d0f..fb6cf7e8194b4e97e17ac1b652ca8cf60d32e52e 100644 (file)
@@ -76,7 +76,7 @@ exports[`should handle re-activation 1`] = `
           >
             type
           </label>
-          <Select
+          <SelectLegacy
             clearable={false}
             disabled={false}
             id="coding-rules-custom-rule-type"
@@ -115,7 +115,7 @@ exports[`should handle re-activation 1`] = `
           >
             severity
           </label>
-          <Select
+          <SelectLegacy
             clearable={false}
             disabled={false}
             id="coding-rules-custom-rule-severity"
@@ -158,7 +158,7 @@ exports[`should handle re-activation 1`] = `
           >
             coding_rules.filters.status
           </label>
-          <Select
+          <SelectLegacy
             clearable={false}
             disabled={false}
             id="coding-rules-custom-rule-status"
@@ -345,7 +345,7 @@ exports[`should render correctly: default 1`] = `
           >
             type
           </label>
-          <Select
+          <SelectLegacy
             clearable={false}
             disabled={false}
             id="coding-rules-custom-rule-type"
@@ -384,7 +384,7 @@ exports[`should render correctly: default 1`] = `
           >
             severity
           </label>
-          <Select
+          <SelectLegacy
             clearable={false}
             disabled={false}
             id="coding-rules-custom-rule-severity"
@@ -427,7 +427,7 @@ exports[`should render correctly: default 1`] = `
           >
             coding_rules.filters.status
           </label>
-          <Select
+          <SelectLegacy
             clearable={false}
             disabled={false}
             id="coding-rules-custom-rule-status"
index 43da92b6dcbbd3a0dc588dbc4ffff793b535260a..f86e9761b8d78e28aa485e757efd9ed0a1cc369f 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import ListIcon from '../../../components/icons/ListIcon';
 import TreeIcon from '../../../components/icons/TreeIcon';
 import TreemapIcon from '../../../components/icons/TreemapIcon';
@@ -76,7 +76,7 @@ export default class MeasureViewSelect extends React.PureComponent<Props> {
 
   render() {
     return (
-      <Select
+      <SelectLegacy
         autoBlur={true}
         className={this.props.className}
         clearable={false}
index 29fe3dbd9eb69dd44bf59f8dd5660b5c630a408b..60095af45a3d0cd7c8723229c6bab0f1526faf17 100644 (file)
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should render correctly: has no list 1`] = `
-<Select
+<SelectLegacy
   autoBlur={true}
   clearable={false}
   onChange={[Function]}
@@ -27,7 +27,7 @@ exports[`should render correctly: has no list 1`] = `
 `;
 
 exports[`should render correctly: has no tree 1`] = `
-<Select
+<SelectLegacy
   autoBlur={true}
   clearable={false}
   onChange={[Function]}
@@ -48,7 +48,7 @@ exports[`should render correctly: has no tree 1`] = `
 `;
 
 exports[`should render correctly: has no treemap 1`] = `
-<Select
+<SelectLegacy
   autoBlur={true}
   clearable={false}
   onChange={[Function]}
index 0445c130997d6c4db865902ddbc3f894a1c66a6f..3e129863e3eb5eafaf74c3054bb1754644dbde29 100644 (file)
@@ -29,7 +29,7 @@ import HelpTooltip from '../../../components/controls/HelpTooltip';
 import Modal from '../../../components/controls/Modal';
 import Radio from '../../../components/controls/Radio';
 import SearchSelect from '../../../components/controls/SearchSelect';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import Tooltip from '../../../components/controls/Tooltip';
 import IssueTypeIcon from '../../../components/icons/IssueTypeIcon';
 import SeverityHelper from '../../../components/shared/SeverityHelper';
@@ -356,7 +356,7 @@ export default class BulkChangeModal extends React.PureComponent<Props, State> {
     );
 
     const input = (
-      <Select
+      <SelectLegacy
         className="input-super-large"
         clearable={true}
         onChange={this.handleSelectFieldChange('type')}
@@ -385,7 +385,7 @@ export default class BulkChangeModal extends React.PureComponent<Props, State> {
     }));
 
     const input = (
-      <Select
+      <SelectLegacy
         className="input-super-large"
         clearable={true}
         onChange={this.handleSelectFieldChange('severity')}
index e24612c56e09df3f76b8a918c1e1c88b1d025a00..58c14d823fbf8882facc5808e588284d119799bb 100644 (file)
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme';
 import * as React from 'react';
 import { searchIssueTags } from '../../../../api/issues';
 import { SubmitButton } from '../../../../components/controls/buttons';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import { mockIssue } from '../../../../helpers/testMocks';
 import { change, waitAndUpdate } from '../../../../helpers/testUtils';
 import BulkChangeModal, { MAX_PAGE_SIZE } from '../BulkChangeModal';
@@ -113,7 +113,7 @@ it('should disable the submit button unless some change is configured', async ()
     expect(wrapper.find(SubmitButton).props().disabled).toBe(true);
 
     const { onChange } = wrapper
-      .find(Select)
+      .find(SelectLegacy)
       .at(0)
       .props();
     if (!onChange) {
index 39870d6a2a0b72eff55e23eb1b6319c4156beb17..15df2627efde65c243ee57cc3dfaa67836cc89dd 100644 (file)
@@ -20,7 +20,7 @@
 import * as React from 'react';
 import { applyTemplateToProject, getPermissionTemplates } from '../../../../api/permissions';
 import { ResetButtonLink, SubmitButton } from '../../../../components/controls/buttons';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import SimpleModal from '../../../../components/controls/SimpleModal';
 import { Alert } from '../../../../components/ui/Alert';
 import DeferredSpinner from '../../../../components/ui/DeferredSpinner';
@@ -125,7 +125,7 @@ export default class ApplyTemplate extends React.PureComponent<Props, State> {
                       <MandatoryFieldMarker />
                     </label>
                     {this.state.permissionTemplates && (
-                      <Select
+                      <SelectLegacy
                         clearable={false}
                         id="project-permissions-template"
                         onChange={this.handlePermissionTemplateChange}
index 89b3a52452031bba5cd0e3b6567c5bd39ae14540..36de38354e61ecced6cc19eb0eda672c47244b4b 100644 (file)
@@ -43,7 +43,7 @@ exports[`render correctly 2`] = `
           template
           <MandatoryFieldMarker />
         </label>
-        <Select
+        <SelectLegacy
           clearable={false}
           id="project-permissions-template"
           onChange={[Function]}
index 328a5d1de1d0edd8517d758ad7338825b51aedab..fe17c39eb297679f04df24b45bbb055722e00094 100644 (file)
@@ -19,7 +19,7 @@
  */
 import classNames from 'classnames';
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { translate } from '../../../helpers/l10n';
 import { APPLICATION_EVENT_TYPES, EVENT_TYPES, Query } from '../utils';
 import ProjectActivityDateInput from './ProjectActivityDateInput';
@@ -48,7 +48,7 @@ export default class ProjectActivityPageHeader extends React.PureComponent<Props
     return (
       <header className="page-header">
         {!['VW', 'SVW'].includes(this.props.project.qualifier) && (
-          <Select
+          <SelectLegacy
             className={classNames('pull-left big-spacer-right', {
               'input-medium': !isApp,
               'input-large': isApp
index 32cb3bbb30f89cfe632a507d665b9e16e8683d0c..17cf32889251eaaabd4e8b2bafc13ac17f7f7cb9 100644 (file)
@@ -4,7 +4,7 @@ exports[`should render correctly the list of series 1`] = `
 <header
   className="page-header"
 >
-  <Select
+  <SelectLegacy
     className="pull-left big-spacer-right input-medium"
     clearable={true}
     onChange={[Function]}
index b5b9d4eeb4a0191aa0bbfcc397905dd58141ce4b..7ebb4cf9fc820e0594cb2a4da09d17a3dd5f27ed 100644 (file)
@@ -20,7 +20,7 @@
 import classNames from 'classnames';
 import * as React from 'react';
 import Radio from '../../../components/controls/Radio';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import Tooltip from '../../../components/controls/Tooltip';
 import DateFormatter from '../../../components/intl/DateFormatter';
 import TimeFormatter from '../../../components/intl/TimeFormatter';
@@ -98,7 +98,7 @@ export default function BranchAnalysisListRenderer(props: BranchAnalysisListRend
     <>
       <div className="spacer-bottom">
         {translate('baseline.analysis_from')}
-        <Select
+        <SelectLegacy
           autoBlur={true}
           className="input-medium spacer-left"
           clearable={false}
index f678446bbefb6d75ece3813877bc8ee90178d87b..44f7ba92bbc4cad6b10fb57787ebfee71ccfbad8 100644 (file)
@@ -6,7 +6,7 @@ exports[`should render correctly: Analyses 1`] = `
     className="spacer-bottom"
   >
     baseline.analysis_from
-    <Select
+    <SelectLegacy
       autoBlur={true}
       className="input-medium spacer-left"
       clearable={false}
@@ -302,7 +302,7 @@ exports[`should render correctly: empty 1`] = `
     className="spacer-bottom"
   >
     baseline.analysis_from
-    <Select
+    <SelectLegacy
       autoBlur={true}
       className="input-medium spacer-left"
       clearable={false}
@@ -346,7 +346,7 @@ exports[`should render correctly: loading 1`] = `
     className="spacer-bottom"
   >
     baseline.analysis_from
-    <Select
+    <SelectLegacy
       autoBlur={true}
       className="input-medium spacer-left"
       clearable={false}
index 044d4423e80000143af48d4be6bb8f4428961685..adc0763cbf52a5f1eac49726710d3c0ee6aa9abe 100644 (file)
@@ -27,7 +27,7 @@ import DisableableSelectOption from '../../components/common/DisableableSelectOp
 import { SubmitButton } from '../../components/controls/buttons';
 import HelpTooltip from '../../components/controls/HelpTooltip';
 import Radio from '../../components/controls/Radio';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
 import { Alert } from '../../components/ui/Alert';
 import { translate } from '../../helpers/l10n';
 import { isDiffMetric } from '../../helpers/measures';
@@ -146,7 +146,7 @@ export default function ProjectQualityGateAppRenderer(props: ProjectQualityGateA
                   {translate('project_quality_gate.always_use_specific')}
                 </div>
                 <div className="display-flex-center">
-                  <Select
+                  <SelectLegacy
                     className="abs-width-300"
                     clearable={false}
                     disabled={submitting || usesDefault}
index 61e9dd74f1d48512a15cfa843a6a85272fd2ac89..bf9b29745b4c0eabeaccdec07adedaab09bdd387 100644 (file)
@@ -20,7 +20,7 @@
 import { shallow } from 'enzyme';
 import * as React from 'react';
 import Radio from '../../../components/controls/Radio';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { mockQualityGate } from '../../../helpers/mocks/quality-gates';
 import { mockCondition } from '../../../helpers/testMocks';
 import { submit } from '../../../helpers/testUtils';
@@ -57,7 +57,7 @@ it('should render correctly', () => {
 it('should render select options correctly', () => {
   return new Promise<void>(resolve => {
     const wrapper = shallowRender();
-    const render = wrapper.find(Select).props().optionRenderer;
+    const render = wrapper.find(SelectLegacy).props().optionRenderer;
 
     expect(render).toBeDefined();
 
@@ -87,7 +87,7 @@ it('should correctly handle changes', () => {
     .onCheck('1');
   expect(onSelect).toHaveBeenLastCalledWith('1');
 
-  wrapper.find(Select).props().onChange!({ value: '2' });
+  wrapper.find(SelectLegacy).props().onChange!({ value: '2' });
   expect(onSelect).toHaveBeenLastCalledWith('2');
 });
 
index 154841d67390b40f5f5872e9ee417c9f322d8e84..2a97f70f0012e4668b73c0d4906f5acd24ff2d95 100644 (file)
@@ -107,7 +107,7 @@ exports[`should render correctly: always use system default 1`] = `
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={true}
@@ -257,7 +257,7 @@ exports[`should render correctly: default 1`] = `
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={false}
@@ -413,7 +413,7 @@ exports[`should render correctly: show new code warning 1`] = `
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={false}
@@ -593,7 +593,7 @@ exports[`should render correctly: show warning 1`] = `
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={false}
@@ -749,7 +749,7 @@ exports[`should render correctly: show warning if not using default 1`] = `
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={true}
@@ -905,7 +905,7 @@ exports[`should render correctly: submitting 1`] = `
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={true}
index 1630c4de3203a4ae4e437e4c2cd2666fcb8be8f8..c01da6619fb7d9116dc3955ce069a714159c6617 100644 (file)
@@ -24,7 +24,7 @@ import { Link } from 'react-router';
 import { Profile } from '../../../api/quality-profiles';
 import DisableableSelectOption from '../../../components/common/DisableableSelectOption';
 import { ButtonLink, SubmitButton } from '../../../components/controls/buttons';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import SimpleModal from '../../../components/controls/SimpleModal';
 import { translate } from '../../../helpers/l10n';
 import { getQualityProfileUrl } from '../../../helpers/urls';
@@ -85,7 +85,7 @@ export function AddLanguageModal(props: AddLanguageModalProps) {
                     {translate('project_quality_profile.add_language_modal.choose_language')}
                   </label>
                 </div>
-                <Select
+                <SelectLegacy
                   className="abs-width-300"
                   clearable={false}
                   disabled={submitting}
@@ -102,7 +102,7 @@ export function AddLanguageModal(props: AddLanguageModalProps) {
                     {translate('project_quality_profile.add_language_modal.choose_profile')}
                   </label>
                 </div>
-                <Select
+                <SelectLegacy
                   className="abs-width-300"
                   clearable={false}
                   disabled={submitting || !language}
index 063502c7278e6efe5a741fb0b3147362082cad9d..a8b021b014e54d27a03b012956ed6c01e787c278 100644 (file)
@@ -23,7 +23,7 @@ import { Profile } from '../../../api/quality-profiles';
 import DisableableSelectOption from '../../../components/common/DisableableSelectOption';
 import { ButtonLink, SubmitButton } from '../../../components/controls/buttons';
 import Radio from '../../../components/controls/Radio';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import SimpleModal from '../../../components/controls/SimpleModal';
 import { Alert } from '../../../components/ui/Alert';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
@@ -119,7 +119,7 @@ export default function SetQualityProfileModal(props: SetQualityProfileModalProp
                       {translate('project_quality_profile.always_use_specific')}
                     </div>
                     <div className="display-flex-center">
-                      <Select
+                      <SelectLegacy
                         className="abs-width-300"
                         clearable={false}
                         disabled={submitting || hasSelectedSysDefault}
index 4c091a9aeeaad6e5eacbd75c08a535f5f9671047..19b31fd2e2c8714c65736b3ca4b6f01a57812a54 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { shallow, ShallowWrapper } from 'enzyme';
 import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import SimpleModal from '../../../../components/controls/SimpleModal';
 import { mockQualityProfile } from '../../../../helpers/testMocks';
 import { AddLanguageModal, AddLanguageModalProps } from '../AddLanguageModal';
@@ -95,13 +95,13 @@ function diveIntoSimpleModal(wrapper: ShallowWrapper) {
 
 function getLanguageSelect(wrapper: ShallowWrapper) {
   return diveIntoSimpleModal(wrapper)
-    .find(Select)
+    .find(SelectLegacy)
     .at(0);
 }
 
 function getProfileSelect(wrapper: ShallowWrapper) {
   return diveIntoSimpleModal(wrapper)
-    .find(Select)
+    .find(SelectLegacy)
     .at(1);
 }
 
index 26a5b40fa88789fec5e39b60808e4c5d21aabc04..e5cf1668eb1fb2e9e19b0162abe44cd6740d7feb 100644 (file)
@@ -20,7 +20,7 @@
 import { shallow, ShallowWrapper } from 'enzyme';
 import * as React from 'react';
 import Radio from '../../../../components/controls/Radio';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import SimpleModal from '../../../../components/controls/SimpleModal';
 import { mockComponent } from '../../../../helpers/mocks/component';
 import { mockQualityProfile } from '../../../../helpers/testMocks';
@@ -35,7 +35,7 @@ it('should render correctly', () => {
 it('should render select options correctly', () => {
   return new Promise<void>((resolve, reject) => {
     const wrapper = shallowRender();
-    const render = wrapper.find(Select).props().optionRenderer;
+    const render = wrapper.find(SelectLegacy).props().optionRenderer;
     if (!render) {
       reject();
       return;
@@ -66,7 +66,7 @@ it('should correctly handle changes', () => {
   expect(onSubmit).toHaveBeenLastCalledWith('foo', 'foo');
 
   const change = diveIntoSimpleModal(wrapper)
-    .find(Select)
+    .find(SelectLegacy)
     .props().onChange;
 
   expect(change).toBeDefined();
index 266194051dcf3136d0b4938d2ddd88b51890bf43..7e6c947970ab8e9385b24d036c639f03b758349f 100644 (file)
@@ -28,7 +28,7 @@ Array [
             project_quality_profile.add_language_modal.choose_language
           </label>
         </div>
-        <Select
+        <SelectLegacy
           className="abs-width-300"
           clearable={false}
           disabled={false}
@@ -61,7 +61,7 @@ Array [
             project_quality_profile.add_language_modal.choose_profile
           </label>
         </div>
-        <Select
+        <SelectLegacy
           className="abs-width-300"
           clearable={false}
           disabled={true}
index 68a7cf2817cbd8db5f6ec5d1e229c97b5c767e36..6455bc57976441d20978ee3e3f1287008c72e553 100644 (file)
@@ -68,7 +68,7 @@ Array [
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={false}
@@ -182,7 +182,7 @@ Array [
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={true}
@@ -296,7 +296,7 @@ Array [
             <div
               className="display-flex-center"
             >
-              <Select
+              <SelectLegacy
                 className="abs-width-300"
                 clearable={false}
                 disabled={false}
index c7168badf4accd68ea41a6201aa36c6f6836738a..38f1c4160e53cee5a10151975d109f87b2d54afb 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 { omit } from 'lodash';
 import * as React from 'react';
+import { components, OptionProps } from 'react-select';
 import Select from '../../../components/controls/Select';
+import BubblesIcon from '../../../components/icons/BubblesIcon';
+import ListIcon from '../../../components/icons/ListIcon';
 import { translate } from '../../../helpers/l10n';
 import { VIEWS, VISUALIZATIONS } from '../utils';
-import PerspectiveSelectOption, { Option } from './PerspectiveSelectOption';
 
 interface Props {
   className?: string;
@@ -30,19 +33,38 @@ interface Props {
   visualization?: string;
 }
 
+export interface PerspectiveOption {
+  type: string;
+  value: string;
+  label: string;
+}
+
 export default class PerspectiveSelect extends React.PureComponent<Props> {
-  handleChange = (option: Option) => {
-    if (option.type === 'view') {
+  handleChange = (option: PerspectiveOption) => {
+    if (option && option.type === 'view') {
       this.props.onChange({ view: option.value });
-    } else if (option.type === 'visualization') {
+    } else if (option && option.type === 'visualization') {
       this.props.onChange({ view: 'visualizations', visualization: option.value });
     }
   };
 
+  perspectiveOptionRender = (props: OptionProps<PerspectiveOption, false>) => {
+    const { data, className } = props;
+    return (
+      <components.Option
+        {...omit(props, ['children', 'className'])}
+        className={`it__projects-perspective-option-${data.value} ${className}`}>
+        {data.type === 'view' && <ListIcon className="little-spacer-right" />}
+        {data.type === 'visualization' && <BubblesIcon className="little-spacer-right" />}
+        {props.children}
+      </components.Option>
+    );
+  };
+
   render() {
     const { view, visualization } = this.props;
     const perspective = view === 'visualizations' ? visualization : view;
-    const options = [
+    const options: PerspectiveOption[] = [
       ...VIEWS.map(opt => ({
         type: 'view',
         value: opt.value,
@@ -56,15 +78,18 @@ export default class PerspectiveSelect extends React.PureComponent<Props> {
     ];
     return (
       <div className={this.props.className}>
-        <label>{translate('projects.perspective')}:</label>
+        <label id="aria-projects-perspective">{translate('projects.perspective')}:</label>
         <Select
-          className="little-spacer-left input-medium"
-          clearable={false}
+          aria-labelledby="aria-projects-perspective"
+          className="little-spacer-left input-medium it__projects-perspective-select"
+          isClearable={false}
           onChange={this.handleChange}
-          optionComponent={PerspectiveSelectOption}
+          components={{
+            Option: this.perspectiveOptionRender
+          }}
           options={options}
-          searchable={false}
-          value={perspective}
+          isSearchable={false}
+          value={options.find(option => option.value === perspective)}
         />
       </div>
     );
diff --git a/server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelectOption.tsx b/server/sonar-web/src/main/js/apps/projects/components/PerspectiveSelectOption.tsx
deleted file mode 100644 (file)
index a9115bc..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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';
-import BubblesIcon from '../../../components/icons/BubblesIcon';
-import ListIcon from '../../../components/icons/ListIcon';
-
-export interface Option {
-  label: string;
-  type: string;
-  value: string;
-}
-
-interface Props {
-  option: Option;
-  children?: React.ReactNode;
-  className?: string;
-  isFocused?: boolean;
-  onFocus: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
-  onSelect: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
-}
-
-export default class PerspectiveSelectOption extends React.PureComponent<Props> {
-  handleMouseDown = (event: React.SyntheticEvent<HTMLElement>) => {
-    event.preventDefault();
-    event.stopPropagation();
-    this.props.onSelect(this.props.option, event);
-  };
-
-  handleMouseEnter = (event: React.SyntheticEvent<HTMLElement>) => {
-    this.props.onFocus(this.props.option, event);
-  };
-
-  handleMouseMove = (event: React.SyntheticEvent<HTMLElement>) => {
-    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}
-        title={option.label}>
-        <div>
-          {option.type === 'view' && <ListIcon className="little-spacer-right" />}
-          {option.type === 'visualization' && <BubblesIcon className="little-spacer-right" />}
-          {this.props.children}
-        </div>
-      </div>
-    );
-  }
-}
index cdf13fbbfac2d9f36504994458619145b681711f..87814b301c78230cfb7549da0ba43627e73452df 100644 (file)
@@ -17,8 +17,9 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-import { sortBy } from 'lodash';
+import { omit, sortBy } from 'lodash';
 import * as React from 'react';
+import { components, OptionProps } from 'react-select';
 import { colors } from '../../../app/theme';
 import { ButtonIcon } from '../../../components/controls/buttons';
 import Select from '../../../components/controls/Select';
@@ -27,7 +28,6 @@ import SortAscIcon from '../../../components/icons/SortAscIcon';
 import SortDescIcon from '../../../components/icons/SortDescIcon';
 import { translate } from '../../../helpers/l10n';
 import { parseSorting, SORTING_LEAK_METRICS, SORTING_METRICS } from '../utils';
-import ProjectsSortingSelectOption, { Option } from './ProjectsSortingSelectOption';
 
 interface Props {
   className?: string;
@@ -37,8 +37,19 @@ interface Props {
   view: string;
 }
 
+export interface Option {
+  label: string;
+  value: string;
+  className?: string;
+  short?: string;
+}
+
 export default class ProjectsSortingSelect extends React.PureComponent<Props> {
-  getSorting = () => parseSorting(this.props.selectedSort);
+  getSorting = () => {
+    const options = this.getOptions();
+    const { sortDesc, sortValue } = parseSorting(this.props.selectedSort);
+    return { sortDesc, value: options.find(o => o.value === sortValue) };
+  };
 
   getOptions = () => {
     const sortMetrics = this.props.view === 'leak' ? SORTING_LEAK_METRICS : SORTING_METRICS;
@@ -46,39 +57,59 @@ export default class ProjectsSortingSelect extends React.PureComponent<Props> {
       option => ({
         value: option.value,
         label: translate('projects.sorting', option.value),
-        class: option.class
+        className: option.class
       })
     );
   };
 
   handleDescToggle = () => {
-    const sorting = this.getSorting();
-    this.props.onChange(sorting.sortValue, !sorting.sortDesc);
+    const { sortDesc, sortValue } = parseSorting(this.props.selectedSort);
+    this.props.onChange(sortValue, !sortDesc);
   };
 
-  handleSortChange = (option: Option) =>
+  handleSortChange = (option: Option) => {
     this.props.onChange(option.value, this.getSorting().sortDesc);
+  };
+
+  projectsSortingSelectOption = (props: OptionProps<Option, false>) => {
+    const { data, children } = props;
+    return (
+      <components.Option
+        {...omit(props, ['children'])}
+        className={`it__project-sort-option-${data.value} ${data.className}`}>
+        {data.short ? data.short : children}
+      </components.Option>
+    );
+  };
 
   render() {
-    const { sortDesc, sortValue } = this.getSorting();
+    const { sortDesc, value } = this.getSorting();
 
     return (
       <div className={this.props.className}>
-        <label>{translate('projects.sort_by')}:</label>
+        <label id="aria-projects-sort">{translate('projects.sort_by')}:</label>
         <Select
-          className="little-spacer-left input-medium"
-          clearable={false}
+          aria-labelledby="aria-projects-sort"
+          className="little-spacer-left input-medium it__projects-sort-select"
+          isClearable={false}
           onChange={this.handleSortChange}
-          optionComponent={ProjectsSortingSelectOption}
+          components={{
+            Option: this.projectsSortingSelectOption
+          }}
           options={this.getOptions()}
-          searchable={false}
-          value={sortValue}
+          isSearchable={false}
+          value={value}
         />
         <Tooltip
           overlay={
             sortDesc ? translate('projects.sort_descending') : translate('projects.sort_ascending')
           }>
           <ButtonIcon
+            aria-label={
+              sortDesc
+                ? translate('projects.sort_descending')
+                : translate('projects.sort_ascending')
+            }
             className="js-projects-sorting-invert spacer-left"
             color={colors.gray60}
             onClick={this.handleDescToggle}>
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelectOption.tsx b/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelectOption.tsx
deleted file mode 100644 (file)
index f7f1615..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 classNames from 'classnames';
-import * as React from 'react';
-
-export interface Option {
-  label: string;
-  value: string;
-  class?: string;
-  short?: string;
-}
-
-interface Props {
-  option: Option;
-  children?: React.ReactNode;
-  className?: string;
-  isFocused?: boolean;
-  onFocus: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
-  onSelect: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
-}
-
-export default class ProjectsSortingSelectOption extends React.PureComponent<Props> {
-  handleMouseDown = (event: React.SyntheticEvent<HTMLElement>) => {
-    event.preventDefault();
-    event.stopPropagation();
-    this.props.onSelect(this.props.option, event);
-  };
-
-  handleMouseEnter = (event: React.SyntheticEvent<HTMLElement>) => {
-    this.props.onFocus(this.props.option, event);
-  };
-
-  handleMouseMove = (event: React.SyntheticEvent<HTMLElement>) => {
-    if (this.props.isFocused) {
-      return;
-    }
-    this.props.onFocus(this.props.option, event);
-  };
-
-  render() {
-    const { option } = this.props;
-    return (
-      <div
-        className={classNames(this.props.className, option.class)}
-        onMouseDown={this.handleMouseDown}
-        onMouseEnter={this.handleMouseEnter}
-        onMouseMove={this.handleMouseMove}
-        title={option.label}>
-        {option.short ? option.short : this.props.children}
-      </div>
-    );
-  }
-}
index c0a9259d55ffdd3d2fdf28eded9a59d3e220894c..b323e18fb9bb40c01a10bf96aadd488995a2e247 100644 (file)
@@ -19,6 +19,9 @@
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
+import BubblesIcon from '../../../../components/icons/BubblesIcon';
+import ListIcon from '../../../../components/icons/ListIcon';
+import { mockReactSelectOptionProps } from '../../../../helpers/mocks/react-select';
 import PerspectiveSelect from '../PerspectiveSelect';
 
 it('should render correctly', () => {
@@ -26,20 +29,36 @@ it('should render correctly', () => {
 });
 
 it('should render with coverage selected', () => {
-  expect(
-    shallow(
-      <PerspectiveSelect onChange={jest.fn()} view="visualizations" visualization="coverage" />
-    )
-  ).toMatchSnapshot();
+  expect(shallowRender({ view: 'visualizations', visualization: 'coverage' })).toMatchSnapshot();
+});
+
+it('should render option correctly', () => {
+  const wrapper = shallowRender();
+  const OptionRender = wrapper.instance().perspectiveOptionRender;
+  let option = shallow(
+    <OptionRender {...mockReactSelectOptionProps({ type: 'view', value: 'test', label: 'test' })} />
+  );
+
+  expect(option.find(ListIcon).type).toBeDefined();
+  option = shallow(
+    <OptionRender
+      {...mockReactSelectOptionProps({ type: 'visualization', value: 'test', label: '' })}
+    />
+  );
+  expect(option.find(BubblesIcon).type).toBeDefined();
 });
 
 it('should handle perspective change correctly', () => {
   const onChange = jest.fn();
-  const instance = shallow(
-    <PerspectiveSelect onChange={onChange} view="visualizations" visualization="coverage" />
-  ).instance() as PerspectiveSelect;
+  const instance = shallowRender({ onChange }).instance();
   instance.handleChange({ label: 'overall', value: 'overall', type: 'view' });
   instance.handleChange({ label: 'leak', value: 'leak', type: 'view' });
   instance.handleChange({ label: 'coverage', value: 'coverage', type: 'visualization' });
   expect(onChange.mock.calls).toMatchSnapshot();
 });
+
+function shallowRender(overrides: Partial<PerspectiveSelect['props']> = {}) {
+  return shallow<PerspectiveSelect>(
+    <PerspectiveSelect onChange={jest.fn()} view="visualizations" {...overrides} />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelectOption-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PerspectiveSelectOption-test.tsx
deleted file mode 100644 (file)
index 737485e..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 PerspectiveSelectOption from '../PerspectiveSelectOption';
-
-it('should render correctly for a view', () => {
-  expect(
-    shallow(
-      <PerspectiveSelectOption
-        onFocus={jest.fn()}
-        onSelect={jest.fn()}
-        option={{ value: 'overall', type: 'view', label: 'Overall' }}>
-        Overall
-      </PerspectiveSelectOption>
-    )
-  ).toMatchSnapshot();
-});
-
-it('should render correctly for a visualization', () => {
-  expect(
-    shallow(
-      <PerspectiveSelectOption
-        onFocus={jest.fn()}
-        onSelect={jest.fn()}
-        option={{ value: 'coverage', type: 'visualization', label: 'Coverage' }}>
-        Coverage
-      </PerspectiveSelectOption>
-    )
-  ).toMatchSnapshot();
-});
-
-it('selects option', () => {
-  const onSelect = jest.fn();
-  const option = { value: 'coverage', type: 'visualization', label: 'Coverage' };
-  const wrapper = shallow(
-    <PerspectiveSelectOption onFocus={jest.fn()} onSelect={onSelect} option={option} />
-  );
-  const event = { stopPropagation() {}, preventDefault() {} };
-  wrapper.simulate('mousedown', event);
-  expect(onSelect).toBeCalledWith(option, event);
-});
-
-it('focuses option', () => {
-  const onFocus = jest.fn();
-  const option = { value: 'coverage', type: 'visualization', label: 'Coverage' };
-  const wrapper = shallow(
-    <PerspectiveSelectOption onFocus={onFocus} onSelect={jest.fn()} option={option} />
-  );
-  const event = { stopPropagation() {}, preventDefault() {} };
-
-  wrapper.simulate('mouseenter', event);
-  expect(onFocus).toBeCalledWith(option, event);
-
-  onFocus.mockClear();
-  wrapper.simulate('mousemove', event);
-  expect(onFocus).toBeCalledWith(option, event);
-
-  onFocus.mockClear();
-  wrapper.setProps({ isFocused: true });
-  wrapper.simulate('mousemove', event);
-  expect(onFocus).not.toBeCalled();
-});
index 5ec93155c70908b9b46802ae674a7435a4e6c58d..3153a5029e24613bf46e650c335fc92360fa1288 100644 (file)
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
+import { GroupTypeBase } from 'react-select';
+import { mockReactSelectOptionProps } from '../../../../helpers/mocks/react-select';
 import { click } from '../../../../helpers/testUtils';
-import ProjectsSortingSelect from '../ProjectsSortingSelect';
+import ProjectsSortingSelect, { Option } from '../ProjectsSortingSelect';
 
 it('should render correctly for overall view', () => {
+  expect(shallowRender()).toMatchSnapshot();
+});
+
+it('should render correctly for leak view', () => {
   expect(
-    shallow(
-      <ProjectsSortingSelect
-        defaultOption="name"
-        onChange={jest.fn()}
-        selectedSort="name"
-        view="overall"
-      />
-    )
+    shallowRender({ defaultOption: 'analysis_date', selectedSort: 'new_coverage', view: 'leak' })
   ).toMatchSnapshot();
 });
 
-it('should render correctly for leak view', () => {
+it('should handle the descending sort direction', () => {
+  expect(shallowRender({ selectedSort: '-vulnerability' })).toMatchSnapshot();
+});
+
+it('should render option correctly', () => {
+  const wrapper = shallowRender();
+  const SortOption = wrapper.instance().projectsSortingSelectOption;
   expect(
     shallow(
-      <ProjectsSortingSelect
-        defaultOption="analysis_date"
-        onChange={jest.fn()}
-        selectedSort="new_coverage"
-        view="leak"
+      <SortOption
+        {...mockReactSelectOptionProps<Option, false, GroupTypeBase<Option>>({
+          label: 'foo',
+          value: 'foo',
+          short: 'fo'
+        })}
       />
     )
   ).toMatchSnapshot();
-});
-
-it('should handle the descending sort direction', () => {
   expect(
     shallow(
-      <ProjectsSortingSelect
-        defaultOption="name"
-        onChange={jest.fn()}
-        selectedSort="-vulnerability"
-        view="overall"
+      <SortOption
+        {...mockReactSelectOptionProps<Option, false, GroupTypeBase<Option>>({
+          label: 'foo',
+          value: 'foo'
+        })}
       />
     )
   ).toMatchSnapshot();
@@ -63,28 +66,29 @@ it('should handle the descending sort direction', () => {
 
 it('changes sorting', () => {
   const onChange = jest.fn();
-  const instance = shallow(
-    <ProjectsSortingSelect
-      defaultOption="name"
-      onChange={onChange}
-      selectedSort="-vulnerabilities"
-      view="overall"
-    />
-  ).instance() as ProjectsSortingSelect;
+  const instance = shallowRender({
+    selectedSort: '-vulnerability',
+    onChange
+  }).instance() as ProjectsSortingSelect;
   instance.handleSortChange({ label: 'size', value: 'size' });
   expect(onChange).toBeCalledWith('size', true);
 });
 
 it('reverses sorting', () => {
   const onChange = jest.fn();
-  const wrapper = shallow(
+  const wrapper = shallowRender({ selectedSort: '-size', onChange });
+  click(wrapper.find('ButtonIcon'));
+  expect(onChange).toBeCalledWith('size', false);
+});
+
+function shallowRender(overrides: Partial<ProjectsSortingSelect['props']> = {}) {
+  return shallow<ProjectsSortingSelect>(
     <ProjectsSortingSelect
       defaultOption="name"
-      onChange={onChange}
-      selectedSort="-size"
+      onChange={jest.fn()}
+      selectedSort="name"
       view="overall"
+      {...overrides}
     />
   );
-  click(wrapper.find('ButtonIcon'));
-  expect(onChange).toBeCalledWith('size', false);
-});
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelectOption-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelectOption-test.tsx
deleted file mode 100644 (file)
index 3cb1258..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 ProjectsSortingSelectOption from '../ProjectsSortingSelectOption';
-
-it('renders', () => {
-  expect(
-    shallow(
-      <ProjectsSortingSelectOption
-        onFocus={jest.fn()}
-        onSelect={jest.fn()}
-        option={{ label: 'Size', value: 'size' }}>
-        Size
-      </ProjectsSortingSelectOption>
-    )
-  ).toMatchSnapshot();
-});
-
-it('renders short', () => {
-  expect(
-    shallow(
-      <ProjectsSortingSelectOption
-        onFocus={jest.fn()}
-        onSelect={jest.fn()}
-        option={{ label: 'Size', short: 'Short', value: 'size' }}>
-        Size
-      </ProjectsSortingSelectOption>
-    )
-  ).toMatchSnapshot();
-});
-
-it('selects option', () => {
-  const onSelect = jest.fn();
-  const option = { value: 'coverage', type: 'visualization', label: 'Coverage' };
-  const wrapper = shallow(
-    <ProjectsSortingSelectOption onFocus={jest.fn()} onSelect={onSelect} option={option} />
-  );
-  const event = { stopPropagation() {}, preventDefault() {} };
-  wrapper.simulate('mousedown', event);
-  expect(onSelect).toBeCalledWith(option, event);
-});
-
-it('focuses option', () => {
-  const onFocus = jest.fn();
-  const option = { value: 'coverage', type: 'visualization', label: 'Coverage' };
-  const wrapper = shallow(
-    <ProjectsSortingSelectOption onFocus={onFocus} onSelect={jest.fn()} option={option} />
-  );
-  const event = { stopPropagation() {}, preventDefault() {} };
-
-  wrapper.simulate('mouseenter', event);
-  expect(onFocus).toBeCalledWith(option, event);
-
-  onFocus.mockClear();
-  wrapper.simulate('mousemove', event);
-  expect(onFocus).toBeCalledWith(option, event);
-
-  onFocus.mockClear();
-  wrapper.setProps({ isFocused: true });
-  wrapper.simulate('mousemove', event);
-  expect(onFocus).not.toBeCalled();
-});
index 807d025e7366aaa3589247cc515d2f47088914ad..24bf353513a4143c4db86373a50a11955f25d109 100644 (file)
@@ -23,15 +23,23 @@ Array [
 
 exports[`should render correctly 1`] = `
 <div>
-  <label>
+  <label
+    id="aria-projects-perspective"
+  >
     projects.perspective
     :
   </label>
   <Select
-    className="little-spacer-left input-medium"
-    clearable={false}
+    aria-labelledby="aria-projects-perspective"
+    className="little-spacer-left input-medium it__projects-perspective-select"
+    components={
+      Object {
+        "Option": [Function],
+      }
+    }
+    isClearable={false}
+    isSearchable={false}
     onChange={[Function]}
-    optionComponent={[Function]}
     options={
       Array [
         Object {
@@ -76,23 +84,36 @@ exports[`should render correctly 1`] = `
         },
       ]
     }
-    searchable={false}
-    value="overall"
+    value={
+      Object {
+        "label": "projects.view.overall",
+        "type": "view",
+        "value": "overall",
+      }
+    }
   />
 </div>
 `;
 
 exports[`should render with coverage selected 1`] = `
 <div>
-  <label>
+  <label
+    id="aria-projects-perspective"
+  >
     projects.perspective
     :
   </label>
   <Select
-    className="little-spacer-left input-medium"
-    clearable={false}
+    aria-labelledby="aria-projects-perspective"
+    className="little-spacer-left input-medium it__projects-perspective-select"
+    components={
+      Object {
+        "Option": [Function],
+      }
+    }
+    isClearable={false}
+    isSearchable={false}
     onChange={[Function]}
-    optionComponent={[Function]}
     options={
       Array [
         Object {
@@ -137,8 +158,13 @@ exports[`should render with coverage selected 1`] = `
         },
       ]
     }
-    searchable={false}
-    value="coverage"
+    value={
+      Object {
+        "label": "projects.visualization.coverage",
+        "type": "visualization",
+        "value": "coverage",
+      }
+    }
   />
 </div>
 `;
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelectOption-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelectOption-test.tsx.snap
deleted file mode 100644 (file)
index 794349a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly for a view 1`] = `
-<div
-  onMouseDown={[Function]}
-  onMouseEnter={[Function]}
-  onMouseMove={[Function]}
-  title="Overall"
->
-  <div>
-    <ListIcon
-      className="little-spacer-right"
-    />
-    Overall
-  </div>
-</div>
-`;
-
-exports[`should render correctly for a visualization 1`] = `
-<div
-  onMouseDown={[Function]}
-  onMouseEnter={[Function]}
-  onMouseMove={[Function]}
-  title="Coverage"
->
-  <div>
-    <BubblesIcon
-      className="little-spacer-right"
-    />
-    Coverage
-  </div>
-</div>
-`;
index e4e2e330431c4dced25b1c8443afecca646a361f..c34e28f2a52d133d6e70d795b28c6af0be28a6df 100644 (file)
@@ -2,71 +2,78 @@
 
 exports[`should handle the descending sort direction 1`] = `
 <div>
-  <label>
+  <label
+    id="aria-projects-sort"
+  >
     projects.sort_by
     :
   </label>
   <Select
-    className="little-spacer-left input-medium"
-    clearable={false}
+    aria-labelledby="aria-projects-sort"
+    className="little-spacer-left input-medium it__projects-sort-select"
+    components={
+      Object {
+        "Option": [Function],
+      }
+    }
+    isClearable={false}
+    isSearchable={false}
     onChange={[Function]}
-    optionComponent={[Function]}
     options={
       Array [
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.name",
           "value": "name",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.analysis_date",
           "value": "analysis_date",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.reliability",
           "value": "reliability",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.security",
           "value": "security",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.security_review",
           "value": "security_review",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.maintainability",
           "value": "maintainability",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.coverage",
           "value": "coverage",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.duplications",
           "value": "duplications",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.size",
           "value": "size",
         },
       ]
     }
-    searchable={false}
-    value="vulnerability"
   />
   <Tooltip
     overlay="projects.sort_descending"
   >
     <ButtonIcon
+      aria-label="projects.sort_descending"
       className="js-projects-sorting-invert spacer-left"
       color="#999"
       onClick={[Function]}
@@ -81,71 +88,85 @@ exports[`should handle the descending sort direction 1`] = `
 
 exports[`should render correctly for leak view 1`] = `
 <div>
-  <label>
+  <label
+    id="aria-projects-sort"
+  >
     projects.sort_by
     :
   </label>
   <Select
-    className="little-spacer-left input-medium"
-    clearable={false}
+    aria-labelledby="aria-projects-sort"
+    className="little-spacer-left input-medium it__projects-sort-select"
+    components={
+      Object {
+        "Option": [Function],
+      }
+    }
+    isClearable={false}
+    isSearchable={false}
     onChange={[Function]}
-    optionComponent={[Function]}
     options={
       Array [
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.analysis_date",
           "value": "analysis_date",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.name",
           "value": "name",
         },
         Object {
-          "class": "projects-leak-sorting-option",
+          "className": "projects-leak-sorting-option",
           "label": "projects.sorting.new_reliability",
           "value": "new_reliability",
         },
         Object {
-          "class": "projects-leak-sorting-option",
+          "className": "projects-leak-sorting-option",
           "label": "projects.sorting.new_security",
           "value": "new_security",
         },
         Object {
-          "class": "projects-leak-sorting-option",
+          "className": "projects-leak-sorting-option",
           "label": "projects.sorting.new_security_review",
           "value": "new_security_review",
         },
         Object {
-          "class": "projects-leak-sorting-option",
+          "className": "projects-leak-sorting-option",
           "label": "projects.sorting.new_maintainability",
           "value": "new_maintainability",
         },
         Object {
-          "class": "projects-leak-sorting-option",
+          "className": "projects-leak-sorting-option",
           "label": "projects.sorting.new_coverage",
           "value": "new_coverage",
         },
         Object {
-          "class": "projects-leak-sorting-option",
+          "className": "projects-leak-sorting-option",
           "label": "projects.sorting.new_duplications",
           "value": "new_duplications",
         },
         Object {
-          "class": "projects-leak-sorting-option",
+          "className": "projects-leak-sorting-option",
           "label": "projects.sorting.new_lines",
           "value": "new_lines",
         },
       ]
     }
-    searchable={false}
-    value="new_coverage"
+    value={
+      Object {
+        "className": "projects-leak-sorting-option",
+        "label": "projects.sorting.new_coverage",
+        "value": "new_coverage",
+      }
+    }
   />
   <Tooltip
     overlay="projects.sort_ascending"
   >
     <ButtonIcon
+      aria-label="projects.sort_ascending"
       className="js-projects-sorting-invert spacer-left"
       color="#999"
       onClick={[Function]}
@@ -160,71 +181,85 @@ exports[`should render correctly for leak view 1`] = `
 
 exports[`should render correctly for overall view 1`] = `
 <div>
-  <label>
+  <label
+    id="aria-projects-sort"
+  >
     projects.sort_by
     :
   </label>
   <Select
-    className="little-spacer-left input-medium"
-    clearable={false}
+    aria-labelledby="aria-projects-sort"
+    className="little-spacer-left input-medium it__projects-sort-select"
+    components={
+      Object {
+        "Option": [Function],
+      }
+    }
+    isClearable={false}
+    isSearchable={false}
     onChange={[Function]}
-    optionComponent={[Function]}
     options={
       Array [
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.name",
           "value": "name",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.analysis_date",
           "value": "analysis_date",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.reliability",
           "value": "reliability",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.security",
           "value": "security",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.security_review",
           "value": "security_review",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.maintainability",
           "value": "maintainability",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.coverage",
           "value": "coverage",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.duplications",
           "value": "duplications",
         },
         Object {
-          "class": undefined,
+          "className": undefined,
           "label": "projects.sorting.size",
           "value": "size",
         },
       ]
     }
-    searchable={false}
-    value="name"
+    value={
+      Object {
+        "className": undefined,
+        "label": "projects.sorting.name",
+        "value": "name",
+      }
+    }
   />
   <Tooltip
     overlay="projects.sort_ascending"
   >
     <ButtonIcon
+      aria-label="projects.sort_ascending"
       className="js-projects-sorting-invert spacer-left"
       color="#999"
       onClick={[Function]}
@@ -236,3 +271,30 @@ exports[`should render correctly for overall view 1`] = `
   </Tooltip>
 </div>
 `;
+
+exports[`should render option correctly 1`] = `
+<Option
+  className="it__project-sort-option-foo undefined"
+  data={
+    Object {
+      "label": "foo",
+      "short": "fo",
+      "value": "foo",
+    }
+  }
+>
+  fo
+</Option>
+`;
+
+exports[`should render option correctly 2`] = `
+<Option
+  className="it__project-sort-option-foo undefined"
+  data={
+    Object {
+      "label": "foo",
+      "value": "foo",
+    }
+  }
+/>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelectOption-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelectOption-test.tsx.snap
deleted file mode 100644 (file)
index 473dc39..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<div
-  className=""
-  onMouseDown={[Function]}
-  onMouseEnter={[Function]}
-  onMouseMove={[Function]}
-  title="Size"
->
-  Size
-</div>
-`;
-
-exports[`renders short 1`] = `
-<div
-  className=""
-  onMouseDown={[Function]}
-  onMouseEnter={[Function]}
-  onMouseMove={[Function]}
-  title="Size"
->
-  Short
-</div>
-`;
index ee10558c61d96990136627fb3510273db4ed99ed..61a7e51d413e26b7926bf79fcbcbe9ce8a0948fc 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { translate } from '../../../helpers/l10n';
 
 interface Props {
@@ -41,7 +41,7 @@ export default class SearchableFilterFooter extends React.PureComponent<Props> {
   render() {
     return (
       <div className="search-navigator-facet-footer projects-facet-footer">
-        <Select
+        <SelectLegacy
           className="input-super-large"
           clearable={false}
           isLoading={this.props.isLoading}
index 19a8cad03a9c828516a1019278278fa3d6200d97..e899747510bc40faccc81e298f9be50254fcfc64 100644 (file)
@@ -19,6 +19,7 @@
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import SearchableFilterFooter from '../SearchableFilterFooter';
 
 const options = [
@@ -36,7 +37,7 @@ it('should render items without the ones in the facet', () => {
       query={{ languages: ['java'] }}
     />
   );
-  expect(wrapper.find('Select').prop('options')).toMatchSnapshot();
+  expect(wrapper.find(SelectLegacy).prop('options')).toMatchSnapshot();
 });
 
 it('should properly handle a change of the facet value', () => {
@@ -49,6 +50,6 @@ it('should properly handle a change of the facet value', () => {
       query={{ languages: ['java'] }}
     />
   );
-  (wrapper.find('Select').prop('onChange') as Function)({ value: 'js' });
+  (wrapper.find(SelectLegacy).prop('onChange') as Function)({ value: 'js' });
   expect(onQueryChange).toBeCalledWith({ languages: 'java,js' });
 });
index d6d907843530a9e41b3b0246a8ed74f735a788c4..284f42c0e2f02b6e9711aafb6df06db8ce5b54ca 100644 (file)
@@ -21,7 +21,7 @@ import * as React from 'react';
 import { bulkApplyTemplate, getPermissionTemplates } from '../../api/permissions';
 import { ResetButtonLink, SubmitButton } from '../../components/controls/buttons';
 import Modal from '../../components/controls/Modal';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
 import { Alert } from '../../components/ui/Alert';
 import MandatoryFieldMarker from '../../components/ui/MandatoryFieldMarker';
 import MandatoryFieldsExplanation from '../../components/ui/MandatoryFieldsExplanation';
@@ -137,7 +137,7 @@ export default class BulkApplyTemplateModal extends React.PureComponent<Props, S
         {translate('template')}
         <MandatoryFieldMarker />
       </label>
-      <Select
+      <SelectLegacy
         clearable={false}
         disabled={this.state.submitting}
         onChange={this.handlePermissionTemplateChange}
index fbf0c4558f25a0de6518388cdb405221783cb731..289a64ba1235907e5965bc165a42b38c2bb05df0 100644 (file)
@@ -25,7 +25,7 @@ import Checkbox from '../../components/controls/Checkbox';
 import DateInput from '../../components/controls/DateInput';
 import HelpTooltip from '../../components/controls/HelpTooltip';
 import SearchBox from '../../components/controls/SearchBox';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
 import QualifierIcon from '../../components/icons/QualifierIcon';
 import { translate } from '../../helpers/l10n';
 import BulkApplyTemplateModal from './BulkApplyTemplateModal';
@@ -136,7 +136,7 @@ export default class Search extends React.PureComponent<Props, State> {
     }
     return (
       <td className="thin nowrap text-middle">
-        <Select
+        <SelectLegacy
           className="input-medium"
           clearable={false}
           disabled={!this.props.ready}
@@ -155,7 +155,7 @@ export default class Search extends React.PureComponent<Props, State> {
   renderVisibilityFilter = () => {
     return (
       <td className="thin nowrap text-middle">
-        <Select
+        <SelectLegacy
           className="input-small"
           clearable={false}
           disabled={!this.props.ready}
index a2e3ce57d6662883565dcfb6e745a161fd11eecc..8647d8cf3dbfc22bcdcb55d9d3540c504be3486f 100644 (file)
@@ -43,7 +43,9 @@ it('render qualifiers filter', () => {
 it('updates qualifier', () => {
   const onQualifierChanged = jest.fn();
   const wrapper = shallowRender({ onQualifierChanged, topLevelQualifiers: ['TRK', 'VW', 'APP'] });
-  wrapper.find('Select[name="projects-qualifier"]').prop<Function>('onChange')({ value: 'VW' });
+  wrapper.find('SelectLegacy[name="projects-qualifier"]').prop<Function>('onChange')({
+    value: 'VW'
+  });
   expect(onQualifierChanged).toBeCalledWith('VW');
 });
 
index a7320df017c52daf2e97fda3e139e29a95e75791..2dbf7ae81fbbb7e952390d8a08c06e5a5a613a43 100644 (file)
@@ -63,7 +63,7 @@ exports[`bulk applies template to all results 2`] = `
         template
         <MandatoryFieldMarker />
       </label>
-      <Select
+      <SelectLegacy
         clearable={false}
         disabled={false}
         onChange={[Function]}
@@ -132,7 +132,7 @@ exports[`bulk applies template to all results 3`] = `
         template
         <MandatoryFieldMarker />
       </label>
-      <Select
+      <SelectLegacy
         clearable={false}
         disabled={true}
         onChange={[Function]}
@@ -270,7 +270,7 @@ exports[`bulk applies template to selected results 2`] = `
         template
         <MandatoryFieldMarker />
       </label>
-      <Select
+      <SelectLegacy
         clearable={false}
         disabled={false}
         onChange={[Function]}
@@ -339,7 +339,7 @@ exports[`bulk applies template to selected results 3`] = `
         template
         <MandatoryFieldMarker />
       </label>
-      <Select
+      <SelectLegacy
         clearable={false}
         disabled={true}
         onChange={[Function]}
index 7af41494b688f480c96642bda3f176a963174528..f6406917fb2b519095d3e1a66c7b46c995d2be31 100644 (file)
@@ -50,7 +50,7 @@ exports[`render qualifiers filter 1`] = `
         <td
           className="thin nowrap text-middle"
         >
-          <Select
+          <SelectLegacy
             className="input-medium"
             clearable={false}
             disabled={false}
@@ -91,7 +91,7 @@ exports[`render qualifiers filter 1`] = `
         <td
           className="thin nowrap text-middle"
         >
-          <Select
+          <SelectLegacy
             className="input-small"
             clearable={false}
             disabled={false}
@@ -205,7 +205,7 @@ exports[`renders 1`] = `
         <td
           className="thin nowrap text-middle"
         >
-          <Select
+          <SelectLegacy
             className="input-small"
             clearable={false}
             disabled={false}
index b1c2b68ae39e8c3a2c1a9c9edafeaa33c87cb381..3f70f2149e679c21010dd5612b886438a171a224 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { translate } from '../../../helpers/l10n';
 import { getPossibleOperators } from '../utils';
 
@@ -49,7 +49,7 @@ export default class ConditionOperator extends React.PureComponent<Props> {
       });
 
       return (
-        <Select
+        <SelectLegacy
           autoFocus={true}
           className="input-medium"
           clearable={false}
index 8875ebe4261a5f311d8d5c4b0bc32927411b2ceb..089d6fafce21e4cc29f8e751f79b0663743464dd 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { sortBy } from 'lodash';
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { getLocalizedMetricDomain, translate } from '../../../helpers/l10n';
 import { getLocalizedMetricNameNoDiffMetric } from '../utils';
 
@@ -73,7 +73,7 @@ export default class MetricSelect extends React.PureComponent<Props> {
     });
 
     return (
-      <Select
+      <SelectLegacy
         className="text-middle quality-gate-metric-select"
         id="condition-metric"
         onChange={this.handleChange}
index ba33e972406b04bb97ddebefe8185151e523fb4f..bf1dc1944a5bd78cf5e45b7ba41f2d698870e1b0 100644 (file)
@@ -20,7 +20,7 @@
 import * as React from 'react';
 import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
 import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import GroupIcon from '../../../components/icons/GroupIcon';
 import Avatar from '../../../components/ui/Avatar';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
@@ -59,7 +59,7 @@ export default function QualityGatePermissionsAddModalRenderer(
         <div className="modal-body">
           <div className="modal-field">
             <label>{translate('quality_gates.permissions.search')}</label>
-            <Select
+            <SelectLegacy
               autoFocus={true}
               className="Select-big"
               clearable={false}
index 4de825249d7b55af23b723f5fb3baa925aef2a01..1776243fe989472eaa67a1dbb1d6d34c61ae1622 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 
 interface Props {
   name: string;
@@ -51,7 +51,7 @@ export default class ThresholdInput extends React.PureComponent<Props> {
     ];
 
     return (
-      <Select
+      <SelectLegacy
         className="input-tiny text-middle"
         clearable={true}
         id="condition-threshold"
index 768106fe36bf79dbb2a0e669b365b5a2e9829105..8daff7a6b5e686ff62f67276a601444fc666b865 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import { mockUserBase } from '../../../../helpers/mocks/users';
 import QualityGatePermissionsAddModalRenderer, {
   QualityGatePermissionsAddModalRendererProps
@@ -40,7 +40,7 @@ it('should render correctly', () => {
 it('should render options correctly', () => {
   const wrapper = shallowRender();
 
-  const { optionRenderer = () => null } = wrapper.find(Select).props();
+  const { optionRenderer = () => null } = wrapper.find(SelectLegacy).props();
 
   expect(optionRenderer({ avatar: 'A', name: 'name', login: 'login' })).toMatchSnapshot('user');
   expect(optionRenderer({ name: 'group name' })).toMatchSnapshot('group');
index ade8d250f5e8340fdb328f82a3cb2a50c1dc641b..02e7b6c63ed762cfa828ff8276b129ea361dea59 100644 (file)
@@ -19,6 +19,7 @@
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import { change } from '../../../../helpers/testUtils';
 import ThresholdInput from '../ThresholdInput';
 
@@ -48,7 +49,7 @@ describe('on ratings', () => {
   it('should render Select', () => {
     const select = shallow(
       <ThresholdInput metric={metric} name="foo" onChange={jest.fn()} value="2" />
-    ).find('Select');
+    ).find(SelectLegacy);
     expect(select.length).toEqual(1);
     expect(select.prop('value')).toEqual('2');
   });
@@ -57,7 +58,7 @@ describe('on ratings', () => {
     const onChange = jest.fn();
     const select = shallow(
       <ThresholdInput metric={metric} name="foo" onChange={onChange} value="2" />
-    ).find('Select');
+    ).find(SelectLegacy);
     (select.prop('onChange') as Function)({ label: 'D', value: '4' });
     expect(onChange).toBeCalledWith('4');
   });
@@ -66,7 +67,7 @@ describe('on ratings', () => {
     const onChange = jest.fn();
     const select = shallow(
       <ThresholdInput metric={metric} name="foo" onChange={onChange} value="2" />
-    ).find('Select');
+    ).find(SelectLegacy);
     (select.prop('onChange') as Function)(null);
     expect(onChange).toBeCalledWith('');
   });
index a229502920f3b47c760885271216641ba2c87127..b5271694236826aa11d3aff05bacf685e91472de 100644 (file)
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should render correctly 1`] = `
-<Select
+<SelectLegacy
   autoFocus={true}
   className="input-medium"
   clearable={false}
index a8e13546bdefc9a3952d7e61179f41cdd709e821..1d2d3106f238640ae71f06fd65d3ee67d06e402c 100644 (file)
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should render correctly 1`] = `
-<Select
+<SelectLegacy
   className="text-middle quality-gate-metric-select"
   id="condition-metric"
   onChange={[Function]}
index db838460f7dabb94289726a7e0b8a2f983aaeeaa..7be52876dcf1cae3d618db49edb75ff82fffa98c 100644 (file)
@@ -24,7 +24,7 @@ exports[`should render correctly: default 1`] = `
         <label>
           quality_gates.permissions.search
         </label>
-        <Select
+        <SelectLegacy
           autoFocus={true}
           className="Select-big"
           clearable={false}
@@ -83,7 +83,7 @@ exports[`should render correctly: query and results 1`] = `
         <label>
           quality_gates.permissions.search
         </label>
-        <Select
+        <SelectLegacy
           autoFocus={true}
           className="Select-big"
           clearable={false}
@@ -153,7 +153,7 @@ exports[`should render correctly: selection 1`] = `
         <label>
           quality_gates.permissions.search
         </label>
-        <Select
+        <SelectLegacy
           autoFocus={true}
           className="Select-big"
           clearable={false}
@@ -217,7 +217,7 @@ exports[`should render correctly: short query 1`] = `
         <label>
           quality_gates.permissions.search
         </label>
-        <Select
+        <SelectLegacy
           autoFocus={true}
           className="Select-big"
           clearable={false}
@@ -276,7 +276,7 @@ exports[`should render correctly: submitting 1`] = `
         <label>
           quality_gates.permissions.search
         </label>
-        <Select
+        <SelectLegacy
           autoFocus={true}
           className="Select-big"
           clearable={false}
index d17f303ea555ecd7db708bad668bd590387d224a..ae1e63e17860083679b53b14b34a7046e674144f 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import Tooltip from '../../../components/controls/Tooltip';
 import { translate } from '../../../helpers/l10n';
 import { Profile } from '../types';
@@ -57,7 +57,7 @@ export default class ComparisonForm extends React.PureComponent<Props> {
     return (
       <div className="display-inline-block">
         <label className="spacer-right">{translate('quality_profiles.compare_with')}</label>
-        <Select
+        <SelectLegacy
           className="input-large"
           clearable={false}
           onChange={this.handleChange}
index c44231aafe0e863fc9dd47a65ec20e1eb7df2821..031e457f65f61e45f08e61704f8890c116412c80 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import { mockQualityProfile } from '../../../../helpers/testMocks';
 import ComparisonForm from '../ComparisonForm';
 
@@ -40,7 +40,7 @@ it('should render Select with right options', () => {
       profiles={profiles}
       withKey="another"
     />
-  ).find(Select);
+  ).find(SelectLegacy);
   expect(output.props().valueRenderer!(profileDefault)).toMatchSnapshot('Render default for value');
   expect(output.props().valueRenderer!(profile)).toMatchSnapshot('Render for value');
 
index 60ce4e975e744dcd70216c95407d84acfcb256f7..15d95f73662f5ed6fed5c0ed65d7a8f2a21ced9e 100644 (file)
@@ -22,7 +22,7 @@ import * as React from 'react';
 import { changeProfileParent } from '../../../api/quality-profiles';
 import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
 import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
 import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
 import { translate } from '../../../helpers/l10n';
@@ -108,7 +108,7 @@ export default class ChangeParentForm extends React.PureComponent<Props, State>
                 {translate('quality_profiles.parent')}
                 <MandatoryFieldMarker />
               </label>
-              <Select
+              <SelectLegacy
                 clearable={false}
                 id="change-profile-parent"
                 name="parentKey"
index cdacf1c9431fc5e5cbddda5c3fa5cb793a282b90..df95a313f114576d84b7c45ea79434563b04c130 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { debounce, identity } from 'lodash';
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import GroupIcon from '../../../components/icons/GroupIcon';
 import Avatar from '../../../components/ui/Avatar';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
@@ -91,7 +91,7 @@ export default class ProfilePermissionsFormSelect extends React.PureComponent<Pr
     const options = this.state.searchResults.map(r => ({ ...r, value: getStringValue(r) }));
 
     return (
-      <Select
+      <SelectLegacy
         autoFocus={true}
         className="Select-big"
         clearable={false}
index 95203d35adb4a2b963580583aab8d7f1224d7f38..d1e22c888d76b0a45df8e706eea4a41b6034badc 100644 (file)
@@ -32,7 +32,7 @@ exports[`should render correctly 1`] = `
           quality_profiles.parent
           <MandatoryFieldMarker />
         </label>
-        <Select
+        <SelectLegacy
           clearable={false}
           id="change-profile-parent"
           name="parentKey"
index 4119a215923c0a7dd0bcb9a3a947894a8736fc68..eb0697492a56738ed310c47042d0d597b3af72bf 100644 (file)
@@ -26,7 +26,7 @@ import {
 } from '../../../api/quality-profiles';
 import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
 import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { Location } from '../../../components/hoc/withRouter';
 import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
 import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
@@ -174,7 +174,7 @@ export default class CreateProfileForm extends React.PureComponent<Props, State>
                   {translate('language')}
                   <MandatoryFieldMarker />
                 </label>
-                <Select
+                <SelectLegacy
                   clearable={false}
                   id="create-profile-language"
                   name="language"
@@ -191,7 +191,7 @@ export default class CreateProfileForm extends React.PureComponent<Props, State>
                   <label htmlFor="create-profile-parent">
                     {translate('quality_profiles.parent')}
                   </label>
-                  <Select
+                  <SelectLegacy
                     clearable={true}
                     id="create-profile-parent"
                     name="parentKey"
index 148113653aa129fb5ed81da8a0f8527725acc359..e45f7de71e72dfc8461e48d75bc2d0fe56fc5a0d 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { Router, withRouter } from '../../../components/hoc/withRouter';
 import { translate } from '../../../helpers/l10n';
 import { getProfilesForLanguagePath, PROFILE_PATH } from '../utils';
@@ -52,7 +52,7 @@ export class ProfilesListHeader extends React.PureComponent<Props> {
     return (
       <header className="quality-profiles-list-header clearfix">
         <span className="spacer-right">{translate('quality_profiles.filter_by')}:</span>
-        <Select
+        <SelectLegacy
           className="input-medium"
           clearable={true}
           onChange={this.handleChange}
index cab26031cd21bece003ddff5a5deea1148af2269..9dd1840dadb8d65658d4e7e1e4447493cf7fedbf 100644 (file)
@@ -53,7 +53,7 @@ exports[`should render correctly: default 1`] = `
           language
           <MandatoryFieldMarker />
         </label>
-        <Select
+        <SelectLegacy
           clearable={false}
           id="create-profile-language"
           name="language"
@@ -81,7 +81,7 @@ exports[`should render correctly: default 1`] = `
         >
           quality_profiles.parent
         </label>
-        <Select
+        <SelectLegacy
           clearable={true}
           id="create-profile-parent"
           name="parentKey"
@@ -180,7 +180,7 @@ exports[`should render correctly: with query filter 1`] = `
           language
           <MandatoryFieldMarker />
         </label>
-        <Select
+        <SelectLegacy
           clearable={false}
           id="create-profile-language"
           name="language"
@@ -208,7 +208,7 @@ exports[`should render correctly: with query filter 1`] = `
         >
           quality_profiles.parent
         </label>
-        <Select
+        <SelectLegacy
           clearable={true}
           id="create-profile-parent"
           name="parentKey"
index 95e39f0ca5dd74f93075f3bf46e5284c558be60e..951c3ef3e312a371b4750c0ebabf5c59f3d5d044 100644 (file)
@@ -10,7 +10,7 @@ exports[`should render correctly 1`] = `
     quality_profiles.filter_by
     :
   </span>
-  <Select
+  <SelectLegacy
     className="input-medium"
     clearable={true}
     onChange={[Function]}
index 30efa3ebf288086cc0bbd916fe1bb3b7e03f050d..ffbb0d81a72d0a32837203eec06327c63d4523ab 100644 (file)
@@ -20,7 +20,7 @@
 import * as React from 'react';
 import HelpTooltip from '../../../components/controls/HelpTooltip';
 import RadioToggle from '../../../components/controls/RadioToggle';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
 import Measure from '../../../components/measure/Measure';
 import CoverageRating from '../../../components/ui/CoverageRating';
@@ -107,7 +107,7 @@ export function FilterBar(props: FilterBarProps) {
                 )}
 
                 <span className="spacer-right">{translate('status')}</span>
-                <Select
+                <SelectLegacy
                   className="input-medium big-spacer-right"
                   clearable={false}
                   onChange={(option: { value: HotspotStatusFilter }) =>
@@ -119,7 +119,7 @@ export function FilterBar(props: FilterBarProps) {
                 />
 
                 {onBranch && (
-                  <Select
+                  <SelectLegacy
                     className="input-medium big-spacer-right"
                     clearable={false}
                     onChange={(option: { value: boolean }) =>
index 5f920cd0178bceeac94f7c06c013a9db9029c76e..9c49548558e286b878c42b83519ea79a8b7c56b3 100644 (file)
@@ -20,7 +20,7 @@
 import { shallow } from 'enzyme';
 import * as React from 'react';
 import RadioToggle from '../../../../components/controls/RadioToggle';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import { mockComponent } from '../../../../helpers/mocks/component';
 import { mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
 import { ComponentQualifier } from '../../../../types/component';
@@ -60,7 +60,7 @@ it('should trigger onChange for status', () => {
   const wrapper = shallowRender({ onChangeFilters });
 
   const { onChange } = wrapper
-    .find(Select)
+    .find(SelectLegacy)
     .at(0)
     .props();
 
@@ -83,7 +83,7 @@ it('should trigger onChange for leak period', () => {
   const wrapper = shallowRender({ onChangeFilters });
 
   const { onChange } = wrapper
-    .find(Select)
+    .find(SelectLegacy)
     .at(1)
     .props();
 
index b45ba01e3c864fe3fbd75cc66910b33f3d87a1d8..2332ce7de08ba1bb396a7922ab85702e018c5805 100644 (file)
@@ -49,7 +49,7 @@ exports[`should render correctly: anonymous 1`] = `
           >
             status
           </span>
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
@@ -72,7 +72,7 @@ exports[`should render correctly: anonymous 1`] = `
             searchable={false}
             value="TO_REVIEW"
           />
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
@@ -165,7 +165,7 @@ exports[`should render correctly: logged-in 1`] = `
           >
             status
           </span>
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
@@ -188,7 +188,7 @@ exports[`should render correctly: logged-in 1`] = `
             searchable={false}
             value="TO_REVIEW"
           />
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
@@ -281,7 +281,7 @@ exports[`should render correctly: non-project 1`] = `
           >
             status
           </span>
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
@@ -304,7 +304,7 @@ exports[`should render correctly: non-project 1`] = `
             searchable={false}
             value="TO_REVIEW"
           />
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
@@ -356,7 +356,7 @@ exports[`should render correctly: on Pull request 1`] = `
           >
             status
           </span>
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
@@ -434,7 +434,7 @@ exports[`should render correctly: with hotspots reviewed measure 1`] = `
           >
             status
           </span>
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
@@ -457,7 +457,7 @@ exports[`should render correctly: with hotspots reviewed measure 1`] = `
             searchable={false}
             value="TO_REVIEW"
           />
-          <Select
+          <SelectLegacy
             className="input-medium big-spacer-right"
             clearable={false}
             onChange={[Function]}
index 7a27154b39820214511285ed61690759d0afe327..9160463cdcbb589ec67dd01a98054cd68cc244c4 100644 (file)
@@ -19,7 +19,7 @@
  */
 import * as React from 'react';
 import { connect } from 'react-redux';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
 import { translate } from '../../../helpers/l10n';
 import { getSettingsAppAllCategories, Store } from '../../../store/rootReducer';
@@ -56,7 +56,7 @@ export function Languages(props: LanguagesProps) {
     <>
       <h2 className="settings-sub-category-name">{translate('property.category.languages')}</h2>
       <div data-test="language-select">
-        <Select
+        <SelectLegacy
           className="input-large"
           onChange={handleOnChange}
           options={availableLanguages}
index 09fde507c1fe531e9fb7351a2473c4db503aec95..687b61d703caf1421f6c5314b32b47cb02ce0beb 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import { mockComponent } from '../../../../helpers/mocks/component';
 import { mockLocation, mockRouter } from '../../../../helpers/testMocks';
 import CategoryDefinitionsList from '../CategoryDefinitionsList';
@@ -41,7 +41,7 @@ it('should correctly handle a change of the selected language', () => {
   const wrapper = shallowRender({ router });
   expect(wrapper.find(CategoryDefinitionsList).props().category).toBe('java');
 
-  const { onChange } = wrapper.find(Select).props();
+  const { onChange } = wrapper.find(SelectLegacy).props();
 
   onChange!({ label: '', originalValue: 'CoBoL', value: 'cobol' });
   expect(push).toHaveBeenCalledWith(expect.objectContaining({ query: { category: 'CoBoL' } }));
index 8f44cf839e0f1b96178ebbe84d12477d586791b6..5fb0112cb1dfb763fc061113226f8ba3cd92d64c 100644 (file)
@@ -10,7 +10,7 @@ exports[`should render correctly 1`] = `
   <div
     data-test="language-select"
   >
-    <Select
+    <SelectLegacy
       className="input-large"
       onChange={[Function]}
       options={
@@ -56,7 +56,7 @@ exports[`should render correctly with an unknow language 1`] = `
   <div
     data-test="language-select"
   >
-    <Select
+    <SelectLegacy
       className="input-large"
       onChange={[Function]}
       options={
index f994fb8011a174639292c939ef8e78185f4fcea6..e3daa42b85896ed5e6ea19e56c8a10daeb1cb0c9 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import { SettingCategoryDefinition } from '../../../../types/settings';
 import { DefaultSpecializedInputProps } from '../../utils';
 
@@ -36,7 +36,7 @@ export default class InputForSingleSelectList extends React.PureComponent<Props>
     }));
 
     return (
-      <Select
+      <SelectLegacy
         className="settings-large-input"
         clearable={false}
         name={this.props.name}
index 00d5fcb467ae6496ad33188f5febd1721f158f7c..7d1a91f9c1de3c90e3e4d544efecc940e4a2fae0 100644 (file)
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
+import SelectLegacy from '../../../../../components/controls/SelectLegacy';
 import { mockSetting } from '../../../../../helpers/mocks/settings';
 import { DefaultSpecializedInputProps } from '../../../utils';
 import InputForSingleSelectList from '../InputForSingleSelectList';
 
 it('should render Select', () => {
   const onChange = jest.fn();
-  const select = shallowRender({ onChange }).find('Select');
+  const select = shallowRender({ onChange }).find(SelectLegacy);
   expect(select.length).toBe(1);
   expect(select.prop('name')).toBe('foo');
   expect(select.prop('value')).toBe('bar');
@@ -39,7 +40,7 @@ it('should render Select', () => {
 
 it('should call onChange', () => {
   const onChange = jest.fn();
-  const select = shallowRender({ onChange }).find('Select');
+  const select = shallowRender({ onChange }).find(SelectLegacy);
   expect(select.length).toBe(1);
   expect(select.prop('onChange')).toBeDefined();
 
index 7f1b00581608ab590439bba4d51df5d8790b208c..352cc27c1d61326de8620a4a3c585645e0b3d383 100644 (file)
@@ -21,7 +21,7 @@ import * as React from 'react';
 import { FormattedMessage } from 'react-intl';
 import { Link } from 'react-router';
 import { Button, SubmitButton } from '../../../../components/controls/buttons';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
 import AlertSuccessIcon from '../../../../components/icons/AlertSuccessIcon';
 import { Alert } from '../../../../components/ui/Alert';
 import DeferredSpinner from '../../../../components/ui/DeferredSpinner';
@@ -143,7 +143,7 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe
             </div>
           </div>
           <div className="settings-definition-right">
-            <Select
+            <SelectLegacy
               autosize={true}
               className="abs-width-400 big-spacer-top"
               clearable={false}
index adbe0156488d3bae5ab7ed25d9057323b2f079de..b399c76792dfdf484935c1403f38b48674d03047 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
-import Select from '../../../../../components/controls/Select';
+import SelectLegacy from '../../../../../components/controls/SelectLegacy';
 import { waitAndUpdate } from '../../../../../helpers/testUtils';
 import {
   AlmKeys,
@@ -129,7 +129,7 @@ it('should render select options correctly', async () => {
 
   await waitAndUpdate(wrapper);
 
-  const { optionRenderer } = wrapper.find(Select).props();
+  const { optionRenderer } = wrapper.find(SelectLegacy).props();
 
   expect(optionRenderer!(instances[0])).toMatchSnapshot();
 
index 9325336b54a58ed78ea4aaa11c1d7d7175b87594..1ebb0bf76f4c38ced300cba06f9ac69e6cb46db7 100644 (file)
@@ -129,7 +129,7 @@ exports[`should render correctly: when there are configuration errors (admin use
       <div
         className="settings-definition-right"
       >
-        <Select
+        <SelectLegacy
           autosize={true}
           className="abs-width-400 big-spacer-top"
           clearable={false}
@@ -331,7 +331,7 @@ exports[`should render correctly: when there are configuration errors (admin use
       <div
         className="settings-definition-right"
       >
-        <Select
+        <SelectLegacy
           autosize={true}
           className="abs-width-400 big-spacer-top"
           clearable={false}
@@ -473,7 +473,7 @@ exports[`should render correctly: when there are configuration errors (non-admin
       <div
         className="settings-definition-right"
       >
-        <Select
+        <SelectLegacy
           autosize={true}
           className="abs-width-400 big-spacer-top"
           clearable={false}
@@ -618,7 +618,7 @@ exports[`should render correctly: with a single ALM instance 1`] = `
       <div
         className="settings-definition-right"
       >
-        <Select
+        <SelectLegacy
           autosize={true}
           className="abs-width-400 big-spacer-top"
           clearable={false}
@@ -700,7 +700,7 @@ exports[`should render correctly: with a valid and saved form 1`] = `
       <div
         className="settings-definition-right"
       >
-        <Select
+        <SelectLegacy
           autosize={true}
           className="abs-width-400 big-spacer-top"
           clearable={false}
@@ -859,7 +859,7 @@ exports[`should render correctly: with an empty form 1`] = `
       <div
         className="settings-definition-right"
       >
-        <Select
+        <SelectLegacy
           autosize={true}
           className="abs-width-400 big-spacer-top"
           clearable={false}
index 9676bf12248c5902a2b1ddbcd30554024c47b956..b802c2d71c463e56c018a992ed082e9ecfdae4f4 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { debounce } from 'lodash';
 import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
 import Avatar from '../../../components/ui/Avatar';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 
@@ -110,7 +110,7 @@ export default class UsersSelectSearch extends React.PureComponent<Props, State>
         ? translateWithParameters('select2.tooShort', 2)
         : translate('no_results');
     return (
-      <Select
+      <SelectLegacy
         autoFocus={this.props.autoFocus}
         className="Select-big"
         clearable={false}
index 7b68987e6b3a69031aa286c9c0c0e10d1ed89c7f..c3e1c99564e8d4c20eaf34b1a53bcd3bac771270 100644 (file)
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`UsersSelectSearch should render correctly 1`] = `
-<Select
+<SelectLegacy
   className="Select-big"
   clearable={false}
   filterOptions={[Function]}
@@ -42,7 +42,7 @@ Array [
 `;
 
 exports[`UsersSelectSearch should render correctly 3`] = `
-<Select
+<SelectLegacy
   className="Select-big"
   clearable={false}
   filterOptions={[Function]}
index fdc9cf287bf31ad6b2e742f6c293340a22978029..e783b394cefdbff274ba4f54dc07217d0c730f2f 100644 (file)
@@ -19,9 +19,9 @@
  */
 import classNames from 'classnames';
 import * as React from 'react';
-import Select from '../../components/controls/Select';
 import { translate } from '../../helpers/l10n';
 import { GraphType } from '../../types/project-activity';
+import SelectLegacy from '../controls/SelectLegacy';
 import AddGraphMetric from './AddGraphMetric';
 import './styles.css';
 import { getGraphTypes, isCustomGraph } from './utils';
@@ -64,7 +64,7 @@ export default class GraphsHeader extends React.PureComponent<Props> {
 
     return (
       <div className={classNames(className, 'position-relative')}>
-        <Select
+        <SelectLegacy
           className="pull-left input-medium"
           clearable={false}
           onChange={this.handleGraphChange}
index b484e952e471239c4683239b15e71c684ef50489..de7cb47b4d9578f5e450fde255313ca92a60e494 100644 (file)
@@ -25,13 +25,13 @@ import { DayModifiers, Modifier, Modifiers } from 'react-day-picker';
 import { InjectedIntlProps, injectIntl } from 'react-intl';
 import { ButtonIcon, ClearButton } from '../../components/controls/buttons';
 import OutsideClickHandler from '../../components/controls/OutsideClickHandler';
-import Select from '../../components/controls/Select';
 import CalendarIcon from '../../components/icons/CalendarIcon';
 import ChevronLeftIcon from '../../components/icons/ChevronLeftIcon';
 import ChevronRightIcon from '../../components/icons/ChevronRightIcon';
 import { getShortMonthName, getShortWeekDayName, getWeekDayName } from '../../helpers/l10n';
 import { lazyLoadComponent } from '../lazyLoadComponent';
 import './DayPicker.css';
+import SelectLegacy from './SelectLegacy';
 import './styles.css';
 
 const DayPicker = lazyLoadComponent(() => import('react-day-picker'), 'DayPicker');
@@ -172,7 +172,7 @@ export default class DateInput extends React.PureComponent<Props, State> {
                   <ChevronLeftIcon />
                 </ButtonIcon>
                 <div className="date-input-calender-month">
-                  <Select
+                  <SelectLegacy
                     className="date-input-calender-month-select"
                     onChange={this.handleCurrentMonthChange}
                     options={months.map(month => ({
@@ -181,7 +181,7 @@ export default class DateInput extends React.PureComponent<Props, State> {
                     }))}
                     value={this.state.currentMonth.getMonth()}
                   />
-                  <Select
+                  <SelectLegacy
                     className="date-input-calender-month-select spacer-left"
                     onChange={this.handleCurrentYearChange}
                     options={years.map(year => ({ label: String(year), value: year }))}
index cf18ce100f20cefebec77aa90fb964cc7bee14d5..7d6d5edf743119fd87528ab26e5e6990f3ba235a 100644 (file)
@@ -20,7 +20,7 @@
 import { debounce } from 'lodash';
 import * as React from 'react';
 import { translate, translateWithParameters } from '../../helpers/l10n';
-import Select, { Creatable } from './Select';
+import SelectLegacy, { CreatableLegacy } from './SelectLegacy';
 
 interface Props<T> {
   autofocus?: boolean;
@@ -123,7 +123,7 @@ export default class SearchSelect<T extends { value: string }> extends React.Pur
   handleFilterOption = () => true;
 
   render() {
-    const Component = this.props.canCreate ? Creatable : Select;
+    const Component = this.props.canCreate ? CreatableLegacy : SelectLegacy;
     return (
       <Component
         autoFocus={this.autofocus}
diff --git a/server/sonar-web/src/main/js/components/controls/Select.css b/server/sonar-web/src/main/js/components/controls/Select.css
deleted file mode 100644 (file)
index 8f89447..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-.Select {
-  position: relative;
-  display: inline-block;
-  vertical-align: middle;
-  font-size: var(--smallFontSize);
-  text-align: left;
-}
-
-.Select,
-.Select div,
-.Select input,
-.Select span {
-  box-sizing: border-box;
-}
-
-.Select.is-disabled > .Select-control {
-  background-color: var(--disableGrayBg) !important;
-  border-color: var(--disableGrayBorder) !important;
-}
-
-.Select.is-disabled > .Select-control:hover {
-  box-shadow: none !important;
-}
-
-.Select.is-disabled .Select-arrow-zone {
-  cursor: not-allowed !important;
-  pointer-events: none !important;
-}
-
-.Select.is-disabled .Select-placeholder,
-.Select.is-disabled .Select-value {
-  color: var(--disableGrayText) !important;
-}
-
-.Select-control {
-  position: relative;
-  display: table;
-  width: 100%;
-  height: var(--controlHeight);
-  line-height: calc(var(--controlHeight) - 2px);
-  border: 1px solid var(--gray80);
-  border-collapse: separate;
-  border-radius: 2px;
-  background-color: #fff;
-  color: var(--baseFontColor);
-  cursor: default;
-  outline: none;
-  overflow: hidden;
-}
-
-.is-searchable.is-open > .Select-control {
-  cursor: text;
-}
-
-.is-open > .Select-control {
-  border-bottom-right-radius: 0;
-  border-bottom-left-radius: 0;
-  background: #fff;
-}
-
-.is-open > .Select-control > .Select-arrow {
-  border-color: transparent transparent #999;
-  border-width: 0 5px 5px;
-}
-
-.is-searchable.is-focused:not(.is-open) > .Select-control {
-  cursor: text;
-}
-
-.is-focused:not(.is-open) > .Select-control {
-  border-color: var(--blue);
-}
-
-.Select-placeholder {
-  color: var(--secondFontColor);
-}
-
-.Select-placeholder,
-:not(.Select--multi) > .Select-control .Select-value {
-  bottom: 0;
-  left: 0;
-  line-height: 23px;
-  padding-left: 8px;
-  padding-right: 24px;
-  position: absolute;
-  right: 0;
-  top: 0;
-  max-width: 100%;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.Select-value [class^='icon-'] {
-  padding-top: 5px;
-}
-
-.Select-value svg,
-.Select-value img {
-  padding-top: 3px;
-}
-
-.Select-option svg,
-.Select-option img,
-.Select-option [class^='icon-'] {
-  padding-top: 2px;
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value .Select-value-label,
-.has-value.is-pseudo-focused:not(.Select--multi)
-  > .Select-control
-  > .Select-value
-  .Select-value-label {
-  color: var(--baseFontColor);
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label,
-.has-value.is-pseudo-focused:not(.Select--multi)
-  > .Select-control
-  > .Select-value
-  a.Select-value-label {
-  cursor: pointer;
-  text-decoration: none;
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:hover,
-.has-value.is-pseudo-focused:not(.Select--multi)
-  > .Select-control
-  > .Select-value
-  a.Select-value-label:hover,
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:focus,
-.has-value.is-pseudo-focused:not(.Select--multi)
-  > .Select-control
-  > .Select-value
-  a.Select-value-label:focus {
-  color: #007eff;
-  outline: none;
-  text-decoration: underline;
-}
-
-.Select-input {
-  vertical-align: top;
-  height: 22px;
-  padding-left: 8px;
-  padding-right: 8px;
-  outline: none;
-}
-
-.Select-input > input {
-  background: none transparent;
-  border: 0 none;
-  cursor: default;
-  display: inline-block;
-  font-family: inherit;
-  font-size: var(--smallFontSize);
-  height: 22px;
-  margin: 0;
-  outline: none;
-  padding: 0;
-  box-shadow: none;
-  -webkit-appearance: none;
-}
-
-.is-focused .Select-input > input {
-  cursor: text;
-}
-
-.has-value.is-pseudo-focused .Select-input {
-  opacity: 0;
-}
-
-.Select-control:not(.is-searchable) > .Select-input {
-  outline: none;
-}
-
-.Select-loading-zone {
-  cursor: pointer;
-  display: table-cell;
-  position: relative;
-  text-align: center;
-  vertical-align: middle;
-  width: 16px;
-}
-
-.Select-loading {
-  -webkit-animation: Select-animation-spin 400ms infinite linear;
-  -o-animation: Select-animation-spin 400ms infinite linear;
-  animation: Select-animation-spin 400ms infinite linear;
-  width: 16px;
-  height: 16px;
-  box-sizing: border-box;
-  border-radius: 50%;
-  border: 2px solid #ccc;
-  border-right-color: var(--baseFontColor);
-  display: inline-block;
-  position: relative;
-  vertical-align: middle;
-}
-
-.Select-clear-zone {
-  -webkit-animation: Select-animation-fadeIn 200ms;
-  -o-animation: Select-animation-fadeIn 200ms;
-  animation: Select-animation-fadeIn 200ms;
-  color: #999;
-  cursor: pointer;
-  display: table-cell;
-  position: relative;
-  text-align: center;
-  vertical-align: middle;
-  width: 16px;
-  height: 16px;
-  padding-right: 4px;
-}
-
-.Select-clear-zone:hover .Select-clear {
-  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDIzMSwyMCw1Nik7ZmlsbC1ydWxlOm5vbnplcm87Ii8+ICAgIDwvZz48L3N2Zz4=);
-}
-
-.Select-clear {
-  display: block;
-  width: 9px;
-  height: 9px;
-  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDE1MywxNTMsMTUzKTtmaWxsLXJ1bGU6bm9uemVybzsiLz4gICAgPC9nPjwvc3ZnPg==);
-  background-size: 9px 9px;
-  text-indent: -9999px;
-}
-
-.Select--multi .Select-clear-zone {
-  width: 17px;
-}
-
-.Select-arrow-zone {
-  cursor: pointer;
-  display: table-cell;
-  position: relative;
-  text-align: center;
-  vertical-align: middle;
-  width: 20px;
-  padding-right: 5px;
-}
-
-.Select-arrow {
-  border-color: #999 transparent transparent;
-  border-style: solid;
-  border-width: 4px 4px 2px;
-  display: inline-block;
-  height: 0;
-  width: 0;
-}
-
-.is-open .Select-arrow,
-.Select-arrow-zone:hover > .Select-arrow {
-  border-top-color: #666;
-}
-
-@-webkit-keyframes Select-animation-fadeIn {
-  from {
-    opacity: 0;
-  }
-
-  to {
-    opacity: 1;
-  }
-}
-
-@keyframes Select-animation-fadeIn {
-  from {
-    opacity: 0;
-  }
-
-  to {
-    opacity: 1;
-  }
-}
-
-.Select-menu-outer {
-  border-bottom-right-radius: 4px;
-  border-bottom-left-radius: 4px;
-  background-color: #fff;
-  border: 1px solid #ccc;
-  border-top-color: var(--barBorderColor);
-  box-sizing: border-box;
-  margin-top: -1px;
-  max-height: 200px;
-  position: absolute;
-  top: 100%;
-  width: 100%;
-  z-index: var(--dropdownMenuZIndex);
-  -webkit-overflow-scrolling: touch;
-  box-shadow: var(--defaultShadow);
-}
-
-.Select-menu {
-  max-height: 198px;
-  padding: 5px 0;
-  overflow-y: auto;
-}
-
-.Select-option {
-  display: block;
-  line-height: 20px;
-  padding: 0 8px;
-  box-sizing: border-box;
-  color: var(--baseFontColor);
-  font-size: var(--smallFontSize);
-  cursor: pointer;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-.Select-option:last-child {
-  border-bottom-right-radius: 2px;
-  border-bottom-left-radius: 2px;
-}
-
-.Select-option.is-focused {
-  background-color: var(--barBackgroundColor);
-}
-
-.Select-option.is-disabled {
-  cursor: default;
-  opacity: 0.4;
-  font-style: italic;
-}
-
-.Select-noresults {
-  box-sizing: border-box;
-  color: var(--gray60);
-  cursor: default;
-  display: block;
-  padding: 8px 10px;
-}
-
-.Select--multi .Select-value {
-  background-color: rgba(0, 126, 255, 0.08);
-  border-radius: 2px;
-  border: 1px solid rgba(0, 126, 255, 0.24);
-  color: var(--baseFontColor);
-  display: inline-block;
-  font-size: var(--smallFontSize);
-  line-height: 14px;
-  margin: 1px 4px 1px 1px;
-  vertical-align: top;
-}
-
-.Select-value-label {
-  font-size: var(--smallFontSize);
-}
-
-.is-searchable.is-open .Select-value-label {
-  opacity: 0.5;
-}
-
-.Select-big .Select-control {
-  padding-top: 4px;
-  padding-bottom: 4px;
-}
-
-.Select-big .Select-placeholder {
-  margin-top: 4px;
-  margin-bottom: 4px;
-}
-
-.Select-big .Select-value-label {
-  display: inline-block;
-  margin-top: 7px;
-  line-height: 16px;
-}
-
-.Select-big .Select-option {
-  padding: 7px 8px;
-  line-height: 16px;
-}
-
-.Select-big img,
-.Select-big svg {
-  padding-top: 0;
-}
-
-.Select--multi .Select-value-icon,
-.Select--multi .Select-value-label {
-  display: inline-block;
-  vertical-align: middle;
-}
-
-.Select--multi .Select-value-label {
-  display: inline-block;
-  max-width: 200px;
-  border-bottom-right-radius: 2px;
-  border-top-right-radius: 2px;
-  cursor: default;
-  padding: 2px 5px;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.Select--multi a.Select-value-label {
-  color: #007eff;
-  cursor: pointer;
-  text-decoration: none;
-}
-
-.Select--multi a.Select-value-label:hover {
-  text-decoration: underline;
-}
-
-.Select--multi .Select-value-icon {
-  cursor: pointer;
-  border-bottom-left-radius: 2px;
-  border-top-left-radius: 2px;
-  border-right: 1px solid rgba(0, 126, 255, 0.24);
-  padding: 1px 5px;
-}
-
-.Select--multi .Select-value-icon:hover,
-.Select--multi .Select-value-icon:focus {
-  background-color: rgba(0, 113, 230, 0.08);
-  color: #0071e6;
-}
-
-.Select--multi .Select-value-icon:active {
-  background-color: rgba(0, 126, 255, 0.24);
-}
-
-.Select--multi.is-disabled .Select-value {
-  background-color: #fcfcfc;
-  border: 1px solid #e3e3e3;
-  color: var(--baseFontColor);
-}
-
-.Select--multi.is-disabled .Select-value-icon {
-  cursor: not-allowed;
-  border-right: 1px solid #e3e3e3;
-}
-
-.Select--multi.is-disabled .Select-value-icon:hover,
-.Select--multi.is-disabled .Select-value-icon:focus,
-.Select--multi.is-disabled .Select-value-icon:active {
-  background-color: #fcfcfc;
-}
-
-.Select-aria-only {
-  display: none;
-}
-
-@keyframes Select-animation-spin {
-  to {
-    transform: rotate(1turn);
-  }
-}
-
-@-webkit-keyframes Select-animation-spin {
-  to {
-    -webkit-transform: rotate(1turn);
-  }
-}
index cc345e12677b923c06581f1dad9fb131d9d74ad6..bf29eb07b6d401f31a21b06712cc363b5ae2911c 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 styled from '@emotion/styled';
 import * as React from 'react';
-import ReactSelectClass, {
-  ReactAsyncSelectProps,
-  ReactCreatableSelectProps,
-  ReactSelectProps
-} from 'react-select';
-import { lazyLoadComponent } from '../lazyLoadComponent';
-import { ClearButton } from './buttons';
-import './Select.css';
+import ReactSelect, { GroupTypeBase, IndicatorProps, Props, StylesConfig } from 'react-select';
+import { colors, others, sizes, zIndexes } from '../../app/theme';
 
-const ReactSelectLib = import('react-select');
-const ReactSelect = lazyLoadComponent(() => ReactSelectLib);
-const ReactCreatable = lazyLoadComponent(() =>
-  ReactSelectLib.then(lib => ({ default: lib.Creatable }))
-);
-const ReactAsync = lazyLoadComponent(() => ReactSelectLib.then(lib => ({ default: lib.Async })));
+const ArrowSpan = styled.span`
+  border-color: #999 transparent transparent;
+  border-style: solid;
+  border-width: 4px 4px 2px;
+  display: inline-block;
+  height: 0;
+  width: 0;
+`;
 
-function renderInput() {
-  return <ClearButton className="button-tiny spacer-left text-middle" iconProps={{ size: 12 }} />;
-}
-
-export interface WithInnerRef {
-  innerRef?: React.Ref<ReactSelectClass<unknown>>;
-}
+export default function Select<
+  Option,
+  IsMulti extends boolean = false,
+  Group extends GroupTypeBase<Option> = GroupTypeBase<Option>
+>(props: Props<Option, IsMulti, Group>) {
+  function DropdownIndicator({ innerProps }: IndicatorProps<Option, IsMulti, Group>) {
+    return <ArrowSpan {...innerProps} />;
+  }
 
-export default function Select({ innerRef, ...props }: WithInnerRef & ReactSelectProps) {
-  // hide the "x" icon when select is empty
-  const clearable = props.clearable ? Boolean(props.value) : false;
   return (
-    <ReactSelect {...props} clearable={clearable} clearRenderer={renderInput} ref={innerRef} />
+    <ReactSelect
+      {...props}
+      styles={selectStyle<Option, IsMulti, Group>()}
+      components={{
+        ...props.components,
+        DropdownIndicator
+      }}
+    />
   );
 }
 
-export function Creatable(props: ReactCreatableSelectProps) {
-  return <ReactCreatable {...props} clearRenderer={renderInput} />;
-}
-
-export function AsyncSelect(props: ReactAsyncSelectProps & WithInnerRef) {
-  return <ReactAsync {...props} />;
+export function selectStyle<
+  Option,
+  IsMulti extends boolean,
+  Group extends GroupTypeBase<Option>
+>(): StylesConfig<Option, IsMulti, Group> {
+  return {
+    container: () => ({
+      position: 'relative',
+      display: 'inline-block',
+      verticalAlign: 'middle',
+      fontSize: '12px',
+      textAlign: 'left'
+    }),
+    control: () => ({
+      position: 'relative',
+      display: 'table',
+      width: '100%',
+      height: `${sizes.controlHeight}`,
+      lineHeight: `calc(${sizes.controlHeight} - 2px)`,
+      border: `1px solid ${colors.gray80}`,
+      borderCollapse: 'separate',
+      borderRadius: '2px',
+      backgroundColor: '#fff',
+      boxSizing: 'border-box',
+      color: `${colors.baseFontColor}`,
+      cursor: 'default',
+      outline: 'none'
+    }),
+    singleValue: () => ({
+      bottom: 0,
+      left: 0,
+      lineHeight: '23px',
+      paddingLeft: '8px',
+      paddingRight: '24px',
+      position: 'absolute',
+      right: 0,
+      top: 0,
+      maxWidth: '100%',
+      overflow: 'hidden',
+      textOverflow: 'ellipsis',
+      whiteSpace: 'nowrap'
+    }),
+    valueContainer: () => ({
+      bottom: 0,
+      left: 0,
+      lineHeight: '23px',
+      paddingLeft: '8px',
+      paddingRight: '24px',
+      position: 'absolute',
+      right: 0,
+      top: 0,
+      maxWidth: '100%',
+      overflow: 'hidden',
+      textOverflow: 'ellipsis',
+      whiteSpace: 'nowrap'
+    }),
+    indicatorsContainer: () => ({
+      cursor: 'pointer',
+      display: 'table-cell',
+      position: 'relative',
+      textAlign: 'center',
+      verticalAlign: 'middle',
+      width: '20px',
+      paddingRight: '5px'
+    }),
+    menu: () => ({
+      borderBottomRightRadius: '4px',
+      borderBottomLeftRadius: '4px',
+      backgroundColor: '#fff',
+      border: '1px solid #ccc',
+      borderTopColor: `${colors.barBorderColor}`,
+      boxSizing: 'border-box',
+      marginTop: '-1px',
+      maxHeight: '200px',
+      position: 'absolute',
+      top: '100%',
+      width: '100%',
+      zIndex: `${zIndexes.dropdownMenuZIndex}`,
+      webkitOverflowScrolling: 'touch',
+      boxShadow: `${others.defaultShadow}`
+    }),
+    menuList: () => ({
+      maxHeight: '198px',
+      padding: '5px 0',
+      overflowY: 'auto'
+    }),
+    option: (_provided, state) => ({
+      display: 'block',
+      lineHeight: '20px',
+      padding: '0 8px',
+      boxSizing: 'border-box',
+      color: `${colors.baseFontColor}`,
+      backgroundColor: state.isFocused ? `${colors.barBackgroundColor}` : 'white',
+      fontSize: `${sizes.smallFontSize}`,
+      cursor: 'pointer',
+      whiteSpace: 'nowrap',
+      overflow: 'hidden',
+      textOverflow: 'ellipsis'
+    })
+  };
 }
diff --git a/server/sonar-web/src/main/js/components/controls/SelectLegacy.css b/server/sonar-web/src/main/js/components/controls/SelectLegacy.css
new file mode 100644 (file)
index 0000000..8f89447
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.
+ */
+.Select {
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+  font-size: var(--smallFontSize);
+  text-align: left;
+}
+
+.Select,
+.Select div,
+.Select input,
+.Select span {
+  box-sizing: border-box;
+}
+
+.Select.is-disabled > .Select-control {
+  background-color: var(--disableGrayBg) !important;
+  border-color: var(--disableGrayBorder) !important;
+}
+
+.Select.is-disabled > .Select-control:hover {
+  box-shadow: none !important;
+}
+
+.Select.is-disabled .Select-arrow-zone {
+  cursor: not-allowed !important;
+  pointer-events: none !important;
+}
+
+.Select.is-disabled .Select-placeholder,
+.Select.is-disabled .Select-value {
+  color: var(--disableGrayText) !important;
+}
+
+.Select-control {
+  position: relative;
+  display: table;
+  width: 100%;
+  height: var(--controlHeight);
+  line-height: calc(var(--controlHeight) - 2px);
+  border: 1px solid var(--gray80);
+  border-collapse: separate;
+  border-radius: 2px;
+  background-color: #fff;
+  color: var(--baseFontColor);
+  cursor: default;
+  outline: none;
+  overflow: hidden;
+}
+
+.is-searchable.is-open > .Select-control {
+  cursor: text;
+}
+
+.is-open > .Select-control {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  background: #fff;
+}
+
+.is-open > .Select-control > .Select-arrow {
+  border-color: transparent transparent #999;
+  border-width: 0 5px 5px;
+}
+
+.is-searchable.is-focused:not(.is-open) > .Select-control {
+  cursor: text;
+}
+
+.is-focused:not(.is-open) > .Select-control {
+  border-color: var(--blue);
+}
+
+.Select-placeholder {
+  color: var(--secondFontColor);
+}
+
+.Select-placeholder,
+:not(.Select--multi) > .Select-control .Select-value {
+  bottom: 0;
+  left: 0;
+  line-height: 23px;
+  padding-left: 8px;
+  padding-right: 24px;
+  position: absolute;
+  right: 0;
+  top: 0;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.Select-value [class^='icon-'] {
+  padding-top: 5px;
+}
+
+.Select-value svg,
+.Select-value img {
+  padding-top: 3px;
+}
+
+.Select-option svg,
+.Select-option img,
+.Select-option [class^='icon-'] {
+  padding-top: 2px;
+}
+
+.has-value:not(.Select--multi) > .Select-control > .Select-value .Select-value-label,
+.has-value.is-pseudo-focused:not(.Select--multi)
+  > .Select-control
+  > .Select-value
+  .Select-value-label {
+  color: var(--baseFontColor);
+}
+
+.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label,
+.has-value.is-pseudo-focused:not(.Select--multi)
+  > .Select-control
+  > .Select-value
+  a.Select-value-label {
+  cursor: pointer;
+  text-decoration: none;
+}
+
+.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:hover,
+.has-value.is-pseudo-focused:not(.Select--multi)
+  > .Select-control
+  > .Select-value
+  a.Select-value-label:hover,
+.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:focus,
+.has-value.is-pseudo-focused:not(.Select--multi)
+  > .Select-control
+  > .Select-value
+  a.Select-value-label:focus {
+  color: #007eff;
+  outline: none;
+  text-decoration: underline;
+}
+
+.Select-input {
+  vertical-align: top;
+  height: 22px;
+  padding-left: 8px;
+  padding-right: 8px;
+  outline: none;
+}
+
+.Select-input > input {
+  background: none transparent;
+  border: 0 none;
+  cursor: default;
+  display: inline-block;
+  font-family: inherit;
+  font-size: var(--smallFontSize);
+  height: 22px;
+  margin: 0;
+  outline: none;
+  padding: 0;
+  box-shadow: none;
+  -webkit-appearance: none;
+}
+
+.is-focused .Select-input > input {
+  cursor: text;
+}
+
+.has-value.is-pseudo-focused .Select-input {
+  opacity: 0;
+}
+
+.Select-control:not(.is-searchable) > .Select-input {
+  outline: none;
+}
+
+.Select-loading-zone {
+  cursor: pointer;
+  display: table-cell;
+  position: relative;
+  text-align: center;
+  vertical-align: middle;
+  width: 16px;
+}
+
+.Select-loading {
+  -webkit-animation: Select-animation-spin 400ms infinite linear;
+  -o-animation: Select-animation-spin 400ms infinite linear;
+  animation: Select-animation-spin 400ms infinite linear;
+  width: 16px;
+  height: 16px;
+  box-sizing: border-box;
+  border-radius: 50%;
+  border: 2px solid #ccc;
+  border-right-color: var(--baseFontColor);
+  display: inline-block;
+  position: relative;
+  vertical-align: middle;
+}
+
+.Select-clear-zone {
+  -webkit-animation: Select-animation-fadeIn 200ms;
+  -o-animation: Select-animation-fadeIn 200ms;
+  animation: Select-animation-fadeIn 200ms;
+  color: #999;
+  cursor: pointer;
+  display: table-cell;
+  position: relative;
+  text-align: center;
+  vertical-align: middle;
+  width: 16px;
+  height: 16px;
+  padding-right: 4px;
+}
+
+.Select-clear-zone:hover .Select-clear {
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDIzMSwyMCw1Nik7ZmlsbC1ydWxlOm5vbnplcm87Ii8+ICAgIDwvZz48L3N2Zz4=);
+}
+
+.Select-clear {
+  display: block;
+  width: 9px;
+  height: 9px;
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDE1MywxNTMsMTUzKTtmaWxsLXJ1bGU6bm9uemVybzsiLz4gICAgPC9nPjwvc3ZnPg==);
+  background-size: 9px 9px;
+  text-indent: -9999px;
+}
+
+.Select--multi .Select-clear-zone {
+  width: 17px;
+}
+
+.Select-arrow-zone {
+  cursor: pointer;
+  display: table-cell;
+  position: relative;
+  text-align: center;
+  vertical-align: middle;
+  width: 20px;
+  padding-right: 5px;
+}
+
+.Select-arrow {
+  border-color: #999 transparent transparent;
+  border-style: solid;
+  border-width: 4px 4px 2px;
+  display: inline-block;
+  height: 0;
+  width: 0;
+}
+
+.is-open .Select-arrow,
+.Select-arrow-zone:hover > .Select-arrow {
+  border-top-color: #666;
+}
+
+@-webkit-keyframes Select-animation-fadeIn {
+  from {
+    opacity: 0;
+  }
+
+  to {
+    opacity: 1;
+  }
+}
+
+@keyframes Select-animation-fadeIn {
+  from {
+    opacity: 0;
+  }
+
+  to {
+    opacity: 1;
+  }
+}
+
+.Select-menu-outer {
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+  background-color: #fff;
+  border: 1px solid #ccc;
+  border-top-color: var(--barBorderColor);
+  box-sizing: border-box;
+  margin-top: -1px;
+  max-height: 200px;
+  position: absolute;
+  top: 100%;
+  width: 100%;
+  z-index: var(--dropdownMenuZIndex);
+  -webkit-overflow-scrolling: touch;
+  box-shadow: var(--defaultShadow);
+}
+
+.Select-menu {
+  max-height: 198px;
+  padding: 5px 0;
+  overflow-y: auto;
+}
+
+.Select-option {
+  display: block;
+  line-height: 20px;
+  padding: 0 8px;
+  box-sizing: border-box;
+  color: var(--baseFontColor);
+  font-size: var(--smallFontSize);
+  cursor: pointer;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.Select-option:last-child {
+  border-bottom-right-radius: 2px;
+  border-bottom-left-radius: 2px;
+}
+
+.Select-option.is-focused {
+  background-color: var(--barBackgroundColor);
+}
+
+.Select-option.is-disabled {
+  cursor: default;
+  opacity: 0.4;
+  font-style: italic;
+}
+
+.Select-noresults {
+  box-sizing: border-box;
+  color: var(--gray60);
+  cursor: default;
+  display: block;
+  padding: 8px 10px;
+}
+
+.Select--multi .Select-value {
+  background-color: rgba(0, 126, 255, 0.08);
+  border-radius: 2px;
+  border: 1px solid rgba(0, 126, 255, 0.24);
+  color: var(--baseFontColor);
+  display: inline-block;
+  font-size: var(--smallFontSize);
+  line-height: 14px;
+  margin: 1px 4px 1px 1px;
+  vertical-align: top;
+}
+
+.Select-value-label {
+  font-size: var(--smallFontSize);
+}
+
+.is-searchable.is-open .Select-value-label {
+  opacity: 0.5;
+}
+
+.Select-big .Select-control {
+  padding-top: 4px;
+  padding-bottom: 4px;
+}
+
+.Select-big .Select-placeholder {
+  margin-top: 4px;
+  margin-bottom: 4px;
+}
+
+.Select-big .Select-value-label {
+  display: inline-block;
+  margin-top: 7px;
+  line-height: 16px;
+}
+
+.Select-big .Select-option {
+  padding: 7px 8px;
+  line-height: 16px;
+}
+
+.Select-big img,
+.Select-big svg {
+  padding-top: 0;
+}
+
+.Select--multi .Select-value-icon,
+.Select--multi .Select-value-label {
+  display: inline-block;
+  vertical-align: middle;
+}
+
+.Select--multi .Select-value-label {
+  display: inline-block;
+  max-width: 200px;
+  border-bottom-right-radius: 2px;
+  border-top-right-radius: 2px;
+  cursor: default;
+  padding: 2px 5px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.Select--multi a.Select-value-label {
+  color: #007eff;
+  cursor: pointer;
+  text-decoration: none;
+}
+
+.Select--multi a.Select-value-label:hover {
+  text-decoration: underline;
+}
+
+.Select--multi .Select-value-icon {
+  cursor: pointer;
+  border-bottom-left-radius: 2px;
+  border-top-left-radius: 2px;
+  border-right: 1px solid rgba(0, 126, 255, 0.24);
+  padding: 1px 5px;
+}
+
+.Select--multi .Select-value-icon:hover,
+.Select--multi .Select-value-icon:focus {
+  background-color: rgba(0, 113, 230, 0.08);
+  color: #0071e6;
+}
+
+.Select--multi .Select-value-icon:active {
+  background-color: rgba(0, 126, 255, 0.24);
+}
+
+.Select--multi.is-disabled .Select-value {
+  background-color: #fcfcfc;
+  border: 1px solid #e3e3e3;
+  color: var(--baseFontColor);
+}
+
+.Select--multi.is-disabled .Select-value-icon {
+  cursor: not-allowed;
+  border-right: 1px solid #e3e3e3;
+}
+
+.Select--multi.is-disabled .Select-value-icon:hover,
+.Select--multi.is-disabled .Select-value-icon:focus,
+.Select--multi.is-disabled .Select-value-icon:active {
+  background-color: #fcfcfc;
+}
+
+.Select-aria-only {
+  display: none;
+}
+
+@keyframes Select-animation-spin {
+  to {
+    transform: rotate(1turn);
+  }
+}
+
+@-webkit-keyframes Select-animation-spin {
+  to {
+    -webkit-transform: rotate(1turn);
+  }
+}
diff --git a/server/sonar-web/src/main/js/components/controls/SelectLegacy.tsx b/server/sonar-web/src/main/js/components/controls/SelectLegacy.tsx
new file mode 100644 (file)
index 0000000..76b1478
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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';
+import ReactSelectClass, {
+  ReactAsyncSelectProps,
+  ReactCreatableSelectProps,
+  ReactSelectProps
+} from 'react-select-legacy';
+import { lazyLoadComponent } from '../lazyLoadComponent';
+import { ClearButton } from './buttons';
+import './SelectLegacy.css';
+
+const ReactSelectLib = import('react-select-legacy');
+const ReactSelect = lazyLoadComponent(() => ReactSelectLib);
+const ReactCreatable = lazyLoadComponent(() =>
+  ReactSelectLib.then(lib => ({ default: lib.Creatable }))
+);
+const ReactAsync = lazyLoadComponent(() => ReactSelectLib.then(lib => ({ default: lib.Async })));
+
+function renderInput() {
+  return <ClearButton className="button-tiny spacer-left text-middle" iconProps={{ size: 12 }} />;
+}
+
+export interface WithInnerRef {
+  innerRef?: React.Ref<ReactSelectClass<unknown>>;
+}
+
+export default function SelectLegacy({ innerRef, ...props }: WithInnerRef & ReactSelectProps) {
+  // hide the "x" icon when select is empty
+  const clearable = props.clearable ? Boolean(props.value) : false;
+  return (
+    <ReactSelect {...props} clearable={clearable} clearRenderer={renderInput} ref={innerRef} />
+  );
+}
+
+export function CreatableLegacy(props: ReactCreatableSelectProps) {
+  return <ReactCreatable {...props} clearRenderer={renderInput} />;
+}
+
+export function AsyncSelectLegacy(props: ReactAsyncSelectProps & WithInnerRef) {
+  return <ReactAsync {...props} />;
+}
index 2b3bd985de7d1a23ddc11c4ce00b69c23c874a12..77b4c81e5544126c5e7ace2488d02457daa98c85 100644 (file)
 
 import { shallow } from 'enzyme';
 import * as React from 'react';
-import { ReactAsyncSelectProps, ReactCreatableSelectProps, ReactSelectProps } from 'react-select';
-import Select, { AsyncSelect, Creatable, WithInnerRef } from '../Select';
+import { GroupTypeBase, Props } from 'react-select';
+import Select from '../Select';
 
 describe('Select', () => {
-  it('should render correctly', () => {
-    return new Promise<void>((resolve, reject) => {
-      expect(shallowRender()).toMatchSnapshot('default');
-      expect(shallowRender({ clearable: true, value: undefined })).toMatchSnapshot(
-        'disable clear button if no value'
-      );
-
-      const clearRenderFn = shallowRender().props().clearRenderer;
-      if (!clearRenderFn) {
-        reject();
-        return;
-      }
-      expect(clearRenderFn()).toMatchSnapshot('clear button');
-
-      resolve();
-    });
-  });
-
-  function shallowRender(props: Partial<WithInnerRef & ReactSelectProps> = {}) {
-    return shallow<WithInnerRef & ReactSelectProps>(<Select value="foo" {...props} />);
-  }
-});
-
-describe('Creatable', () => {
-  it('should render correctly', () => {
-    return new Promise<void>((resolve, reject) => {
-      expect(shallowRender()).toMatchSnapshot('default');
-
-      const clearRenderFn = shallowRender().props().clearRenderer;
-      if (!clearRenderFn) {
-        reject();
-        return;
-      }
-      expect(clearRenderFn()).toMatchSnapshot('clear button');
-
-      resolve();
-    });
-  });
-
-  function shallowRender(props: Partial<ReactCreatableSelectProps> = {}) {
-    return shallow<ReactCreatableSelectProps>(<Creatable {...props} />);
-  }
-});
-
-describe('AsyncSelect', () => {
   it('should render correctly', () => {
     expect(shallowRender()).toMatchSnapshot('default');
   });
 
-  function shallowRender(props: Partial<WithInnerRef & ReactAsyncSelectProps> = {}) {
-    return shallow<WithInnerRef & ReactAsyncSelectProps>(
-      <AsyncSelect loadOptions={jest.fn()} {...props} />
-    );
+  function shallowRender<
+    Option,
+    IsMulti extends boolean = false,
+    Group extends GroupTypeBase<Option> = GroupTypeBase<Option>
+  >(props: Partial<Props<Option, IsMulti, Group>> = {}) {
+    return shallow<Props<Option, IsMulti, Group>>(<Select {...props} />);
   }
 });
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/SelectLegacy-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/SelectLegacy-test.tsx
new file mode 100644 (file)
index 0000000..b487b81
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 {
+  ReactAsyncSelectProps,
+  ReactCreatableSelectProps,
+  ReactSelectProps
+} from 'react-select-legacy';
+import SelectLegacy, { AsyncSelectLegacy, CreatableLegacy, WithInnerRef } from '../SelectLegacy';
+
+describe('Select', () => {
+  it('should render correctly', () => {
+    return new Promise<void>((resolve, reject) => {
+      expect(shallowRender()).toMatchSnapshot('default');
+      expect(shallowRender({ clearable: true, value: undefined })).toMatchSnapshot(
+        'disable clear button if no value'
+      );
+
+      const clearRenderFn = shallowRender().props().clearRenderer;
+      if (!clearRenderFn) {
+        reject();
+        return;
+      }
+      expect(clearRenderFn()).toMatchSnapshot('clear button');
+
+      resolve();
+    });
+  });
+
+  function shallowRender(props: Partial<WithInnerRef & ReactSelectProps> = {}) {
+    return shallow<WithInnerRef & ReactSelectProps>(<SelectLegacy value="foo" {...props} />);
+  }
+});
+
+describe('Creatable', () => {
+  it('should render correctly', () => {
+    return new Promise<void>((resolve, reject) => {
+      expect(shallowRender()).toMatchSnapshot('default');
+
+      const clearRenderFn = shallowRender().props().clearRenderer;
+      if (!clearRenderFn) {
+        reject();
+        return;
+      }
+      expect(clearRenderFn()).toMatchSnapshot('clear button');
+
+      resolve();
+    });
+  });
+
+  function shallowRender(props: Partial<ReactCreatableSelectProps> = {}) {
+    return shallow<ReactCreatableSelectProps>(<CreatableLegacy {...props} />);
+  }
+});
+
+describe('AsyncSelect', () => {
+  it('should render correctly', () => {
+    expect(shallowRender()).toMatchSnapshot('default');
+  });
+
+  function shallowRender(props: Partial<WithInnerRef & ReactAsyncSelectProps> = {}) {
+    return shallow<WithInnerRef & ReactAsyncSelectProps>(
+      <AsyncSelectLegacy loadOptions={jest.fn()} {...props} />
+    );
+  }
+});
index 5b49a50d0f5730054590dcad089bec00487d6340..457d6cf9d2b418080ac8e8444f71815c488e35fd 100644 (file)
@@ -100,7 +100,7 @@ exports[`should render 3`] = `
         <div
           className="date-input-calender-month"
         >
-          <Select
+          <SelectLegacy
             className="date-input-calender-month-select"
             onChange={[Function]}
             options={
@@ -157,7 +157,7 @@ exports[`should render 3`] = `
             }
             value={0}
           />
-          <Select
+          <SelectLegacy
             className="date-input-calender-month-select spacer-left"
             onChange={[Function]}
             options={
index 792343f1a73b4c44164291040a613516eafb6fc2..9ee6e2df2135eaf5ce8a641f52c206e50f3f18d0 100644 (file)
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should render Select 1`] = `
-<Select
+<SelectLegacy
   autoFocus={true}
   escapeClearsValue={false}
   filterOption={[Function]}
index c96f416934cd61ac0f759b2e90f63cbdf3a2f852..67f7fe54a300e07a53e53306b3626c6f24755a0c 100644 (file)
@@ -1,50 +1,26 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`AsyncSelect should render correctly: default 1`] = `
-<LazyComponentWrapper
-  loadOptions={[MockFunction]}
-/>
-`;
-
-exports[`Creatable should render correctly: clear button 1`] = `
-<ClearButton
-  className="button-tiny spacer-left text-middle"
-  iconProps={
+exports[`Select should render correctly: default 1`] = `
+<StateManager
+  components={
     Object {
-      "size": 12,
+      "DropdownIndicator": [Function],
     }
   }
-/>
-`;
-
-exports[`Creatable should render correctly: default 1`] = `
-<LazyComponentWrapper
-  clearRenderer={[Function]}
-/>
-`;
-
-exports[`Select should render correctly: clear button 1`] = `
-<ClearButton
-  className="button-tiny spacer-left text-middle"
-  iconProps={
+  defaultInputValue=""
+  defaultMenuIsOpen={false}
+  defaultValue={null}
+  styles={
     Object {
-      "size": 12,
+      "container": [Function],
+      "control": [Function],
+      "indicatorsContainer": [Function],
+      "menu": [Function],
+      "menuList": [Function],
+      "option": [Function],
+      "singleValue": [Function],
+      "valueContainer": [Function],
     }
   }
 />
 `;
-
-exports[`Select should render correctly: default 1`] = `
-<LazyComponentWrapper
-  clearRenderer={[Function]}
-  clearable={false}
-  value="foo"
-/>
-`;
-
-exports[`Select should render correctly: disable clear button if no value 1`] = `
-<LazyComponentWrapper
-  clearRenderer={[Function]}
-  clearable={false}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectLegacy-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SelectLegacy-test.tsx.snap
new file mode 100644 (file)
index 0000000..c96f416
--- /dev/null
@@ -0,0 +1,50 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`AsyncSelect should render correctly: default 1`] = `
+<LazyComponentWrapper
+  loadOptions={[MockFunction]}
+/>
+`;
+
+exports[`Creatable should render correctly: clear button 1`] = `
+<ClearButton
+  className="button-tiny spacer-left text-middle"
+  iconProps={
+    Object {
+      "size": 12,
+    }
+  }
+/>
+`;
+
+exports[`Creatable should render correctly: default 1`] = `
+<LazyComponentWrapper
+  clearRenderer={[Function]}
+/>
+`;
+
+exports[`Select should render correctly: clear button 1`] = `
+<ClearButton
+  className="button-tiny spacer-left text-middle"
+  iconProps={
+    Object {
+      "size": 12,
+    }
+  }
+/>
+`;
+
+exports[`Select should render correctly: default 1`] = `
+<LazyComponentWrapper
+  clearRenderer={[Function]}
+  clearable={false}
+  value="foo"
+/>
+`;
+
+exports[`Select should render correctly: disable clear button if no value 1`] = `
+<LazyComponentWrapper
+  clearRenderer={[Function]}
+  clearable={false}
+/>
+`;
diff --git a/server/sonar-web/src/main/js/helpers/mocks/react-select.ts b/server/sonar-web/src/main/js/helpers/mocks/react-select.ts
new file mode 100644 (file)
index 0000000..9940f58
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { GroupTypeBase, OptionProps } from 'react-select';
+
+export function mockReactSelectOptionProps<
+  OptionType,
+  IsMulti extends boolean,
+  GroupType extends GroupTypeBase<OptionType> = GroupTypeBase<OptionType>
+>(
+  data: OptionType,
+  overrides?: OptionProps<OptionType, IsMulti, GroupType>
+): OptionProps<OptionType, IsMulti, GroupType> {
+  return {
+    ...overrides,
+    data
+  } as OptionProps<OptionType, IsMulti, GroupType>;
+}
index df07f16390b1704b6caa53484d9336a091403ba7..e5ba66523739e77821156c0eee000287b51b746c 100644 (file)
@@ -1551,6 +1551,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.8.7":
+  version: 7.16.3
+  resolution: "@babel/runtime@npm:7.16.3"
+  dependencies:
+    regenerator-runtime: ^0.13.4
+  checksum: ab8ac887096d76185ddbf291d28fb976cd32473696dc497ad4905b784acbd5aa462533ad83a5c5104e10ead28c2e0e119840ee28ed8eff90dcdde9d57f916eda
+  languageName: node
+  linkType: hard
+
 "@babel/runtime@npm:^7.3.4":
   version: 7.7.7
   resolution: "@babel/runtime@npm:7.7.7"
@@ -1747,6 +1756,19 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@emotion/cache@npm:^11.4.0, @emotion/cache@npm:^11.6.0":
+  version: 11.6.0
+  resolution: "@emotion/cache@npm:11.6.0"
+  dependencies:
+    "@emotion/memoize": ^0.7.4
+    "@emotion/sheet": ^1.1.0
+    "@emotion/utils": ^1.0.0
+    "@emotion/weak-memoize": ^0.2.5
+    stylis: ^4.0.10
+  checksum: 3c72c50bfe06fd7ec2728988181173664183d2320305a01bb757caa6a9d485de25fccde1b173d810423d2ff88a178d5a72cc21db76b9e458311a8ce3044dd2a1
+  languageName: node
+  linkType: hard
+
 "@emotion/core@npm:10.0.28":
   version: 10.0.28
   resolution: "@emotion/core@npm:10.0.28"
@@ -1774,7 +1796,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@emotion/hash@npm:0.8.0":
+"@emotion/hash@npm:0.8.0, @emotion/hash@npm:^0.8.0":
   version: 0.8.0
   resolution: "@emotion/hash@npm:0.8.0"
   checksum: 4b35d88a97e67275c1d990c96d3b0450451d089d1508619488fc0acb882cb1ac91e93246d471346ebd1b5402215941ef4162efe5b51534859b39d8b3a0e3ffaa
@@ -1797,6 +1819,36 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@emotion/memoize@npm:^0.7.4":
+  version: 0.7.5
+  resolution: "@emotion/memoize@npm:0.7.5"
+  checksum: 83da8d4a7649a92c72f960817692bc6be13cc13e107b9f7e878d63766525ed4402881bfeb3cda61145c050281e7e260f114a0a2870515527346f2ef896b915b3
+  languageName: node
+  linkType: hard
+
+"@emotion/react@npm:^11.1.1":
+  version: 11.6.0
+  resolution: "@emotion/react@npm:11.6.0"
+  dependencies:
+    "@babel/runtime": ^7.13.10
+    "@emotion/cache": ^11.6.0
+    "@emotion/serialize": ^1.0.2
+    "@emotion/sheet": ^1.1.0
+    "@emotion/utils": ^1.0.0
+    "@emotion/weak-memoize": ^0.2.5
+    hoist-non-react-statics: ^3.3.1
+  peerDependencies:
+    "@babel/core": ^7.0.0
+    react: ">=16.8.0"
+  peerDependenciesMeta:
+    "@babel/core":
+      optional: true
+    "@types/react":
+      optional: true
+  checksum: 4fb2d108dc32716d1f162026ac5fdbd0662e3b435a34fb324629d72bb6bff61b18ac8975b51457c16ffa41543bade5d07558566ab76420b3926fbb9159441232
+  languageName: node
+  linkType: hard
+
 "@emotion/serialize@npm:^0.11.15, @emotion/serialize@npm:^0.11.16":
   version: 0.11.16
   resolution: "@emotion/serialize@npm:0.11.16"
@@ -1810,6 +1862,19 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@emotion/serialize@npm:^1.0.0, @emotion/serialize@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "@emotion/serialize@npm:1.0.2"
+  dependencies:
+    "@emotion/hash": ^0.8.0
+    "@emotion/memoize": ^0.7.4
+    "@emotion/unitless": ^0.7.5
+    "@emotion/utils": ^1.0.0
+    csstype: ^3.0.2
+  checksum: ff84fbe09ec06e7ad3deaef5c5b5ea6af6a522e8efe49c2b398b875d06872626284a83b6b18b7f777750c94264a61e7924157d869d9bca2f675731bbb91a6055
+  languageName: node
+  linkType: hard
+
 "@emotion/sheet@npm:0.9.4":
   version: 0.9.4
   resolution: "@emotion/sheet@npm:0.9.4"
@@ -1817,6 +1882,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@emotion/sheet@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "@emotion/sheet@npm:1.1.0"
+  checksum: a4b74e16a8fea1157413efe4904f5f679d724323cb605d66d20a0b98744422f5d411fca927ceb52e4de454a0a819c5273ca9496db9f011b4ecd17b9f1b212007
+  languageName: node
+  linkType: hard
+
 "@emotion/styled-base@npm:^10.0.27":
   version: 10.0.30
   resolution: "@emotion/styled-base@npm:10.0.30"
@@ -1852,7 +1924,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@emotion/unitless@npm:0.7.5":
+"@emotion/unitless@npm:0.7.5, @emotion/unitless@npm:^0.7.5":
   version: 0.7.5
   resolution: "@emotion/unitless@npm:0.7.5"
   checksum: f976e5345b53fae9414a7b2e7a949aa6b52f8bdbcc84458b1ddc0729e77ba1d1dfdff9960e0da60183877873d3a631fa24d9695dd714ed94bcd3ba5196586a6b
@@ -1866,7 +1938,14 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@emotion/weak-memoize@npm:0.2.5":
+"@emotion/utils@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "@emotion/utils@npm:1.0.0"
+  checksum: 3ce8048441a915447d9ef51eb6d1d4cbcce8c8d1647bc7a23333ce2fb2249e74cf9471670d6f49a716e93ff633c9e7a6633517698e17391aebfc40c9d0cabcc0
+  languageName: node
+  linkType: hard
+
+"@emotion/weak-memoize@npm:0.2.5, @emotion/weak-memoize@npm:^0.2.5":
   version: 0.2.5
   resolution: "@emotion/weak-memoize@npm:0.2.5"
   checksum: 27d402b0c683b94658220b6d47840346ee582329ca2a15ec9c233492e0f1a27687ccb233b76eedc922f2e185e444cc89f7b97a81a1d3e5ae9f075bab08e965ea
@@ -2605,6 +2684,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/react-dom@npm:*":
+  version: 17.0.11
+  resolution: "@types/react-dom@npm:17.0.11"
+  dependencies:
+    "@types/react": "*"
+  checksum: 4d5730dffbef86c887cecad7e3cecda424ce6a64d0b5441c63b5b015d48219868660a2bb1aa15e897e565ad8867fa6b885d4358b04e1c4e589ba4c07c3fda55c
+  languageName: node
+  linkType: hard
+
 "@types/react-dom@npm:16.8.4":
   version: 16.8.4
   resolution: "@types/react-dom@npm:16.8.4"
@@ -2659,7 +2747,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/react-select@npm:1.2.6":
+"@types/react-select-legacy@npm:@types/react-select@1.2.6":
   version: 1.2.6
   resolution: "@types/react-select@npm:1.2.6"
   dependencies:
@@ -2668,6 +2756,27 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/react-select@npm:4.0.16":
+  version: 4.0.16
+  resolution: "@types/react-select@npm:4.0.16"
+  dependencies:
+    "@emotion/serialize": ^1.0.0
+    "@types/react": "*"
+    "@types/react-dom": "*"
+    "@types/react-transition-group": "*"
+  checksum: 33a9f5bca7ee3c945f73aa1deeadb0e1220d7721895cb81af96e828b116b9fa64d486bdecad2af8b165047023ba3a87443b43c0ac8acca09f8643f583fb97105
+  languageName: node
+  linkType: hard
+
+"@types/react-transition-group@npm:*":
+  version: 4.4.4
+  resolution: "@types/react-transition-group@npm:4.4.4"
+  dependencies:
+    "@types/react": "*"
+  checksum: 86e9ff9731798e12bc2afe0304678918769633b531dcf6397f86af81718fb7930ef8648e894eeb3718fc6eab6eb885cfb9b82a44d1d74e10951ee11ebc4643ae
+  languageName: node
+  linkType: hard
+
 "@types/react-virtualized@npm:9.21.0":
   version: 9.21.0
   resolution: "@types/react-virtualized@npm:9.21.0"
@@ -2876,7 +2985,8 @@ __metadata:
     "@types/react-modal": 3.12.1
     "@types/react-redux": 6.0.6
     "@types/react-router": 3.0.20
-    "@types/react-select": 1.2.6
+    "@types/react-select": 4.0.16
+    "@types/react-select-legacy": "npm:@types/react-select@1.2.6"
     "@types/react-virtualized": 9.21.0
     "@types/sanitize-html": 1.22.0
     "@types/valid-url": 1.0.2
@@ -2946,7 +3056,8 @@ __metadata:
     react-modal: 3.14.3
     react-redux: 5.1.1
     react-router: 3.2.6
-    react-select: 1.2.1
+    react-select: 4.3.1
+    react-select-legacy: "npm:react-select@1.2.1"
     react-test-renderer: 16.13.0
     react-virtualized: 9.21.2
     redux: 4.0.5
@@ -4875,6 +4986,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"csstype@npm:^3.0.2":
+  version: 3.0.10
+  resolution: "csstype@npm:3.0.10"
+  checksum: 20a8fa324f2b33ddf94aa7507d1b6ab3daa6f3cc308888dc50126585d7952f2471de69b2dbe0635d1fdc31223fef8e070842691877e725caf456e2378685a631
+  languageName: node
+  linkType: hard
+
 "cwd@npm:^0.10.0":
   version: 0.10.0
   resolution: "cwd@npm:0.10.0"
@@ -5312,6 +5430,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"dom-helpers@npm:^5.0.1":
+  version: 5.2.1
+  resolution: "dom-helpers@npm:5.2.1"
+  dependencies:
+    "@babel/runtime": ^7.8.7
+    csstype: ^3.0.2
+  checksum: 863ba9e086f7093df3376b43e74ce4422571d404fc9828bf2c56140963d5edf0e56160f9b2f3bb61b282c07f8fc8134f023c98fd684bddcb12daf7b0f14d951c
+  languageName: node
+  linkType: hard
+
 "dom-serializer@npm:0, dom-serializer@npm:~0.1.1":
   version: 0.1.1
   resolution: "dom-serializer@npm:0.1.1"
@@ -7192,7 +7320,7 @@ fsevents@~2.3.2:
   languageName: node
   linkType: hard
 
-"hoist-non-react-statics@npm:^3.3.2":
+"hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2":
   version: 3.3.2
   resolution: "hoist-non-react-statics@npm:3.3.2"
   dependencies:
@@ -9534,6 +9662,13 @@ fsevents@~2.3.2:
   languageName: node
   linkType: hard
 
+"memoize-one@npm:^5.0.0":
+  version: 5.2.1
+  resolution: "memoize-one@npm:5.2.1"
+  checksum: a3cba7b824ebcf24cdfcd234aa7f86f3ad6394b8d9be4c96ff756dafb8b51c7f71320785fbc2304f1af48a0467cbbd2a409efc9333025700ed523f254cb52e3d
+  languageName: node
+  linkType: hard
+
 "merge-stream@npm:^2.0.0":
   version: 2.0.0
   resolution: "merge-stream@npm:2.0.0"
@@ -11513,6 +11648,17 @@ fsevents@~2.3.2:
   languageName: node
   linkType: hard
 
+"react-input-autosize@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "react-input-autosize@npm:3.0.0"
+  dependencies:
+    prop-types: ^15.5.8
+  peerDependencies:
+    react: ^16.3.0 || ^17.0.0
+  checksum: cc3309ddc87446ade742c7d0e88ef089dd8b6981f21506a2bb27daf01a8803ac697f64157c4ffc7e81dfcf3892b54a4072dbc3652fd9addcf6d22dd0b87ab723
+  languageName: node
+  linkType: hard
+
 "react-intl@npm:2.8.0":
   version: 2.8.0
   resolution: "react-intl@npm:2.8.0"
@@ -11601,7 +11747,7 @@ fsevents@~2.3.2:
   languageName: node
   linkType: hard
 
-"react-select@npm:1.2.1":
+"react-select-legacy@npm:react-select@1.2.1":
   version: 1.2.1
   resolution: "react-select@npm:1.2.1"
   dependencies:
@@ -11615,6 +11761,24 @@ fsevents@~2.3.2:
   languageName: node
   linkType: hard
 
+"react-select@npm:4.3.1":
+  version: 4.3.1
+  resolution: "react-select@npm:4.3.1"
+  dependencies:
+    "@babel/runtime": ^7.12.0
+    "@emotion/cache": ^11.4.0
+    "@emotion/react": ^11.1.1
+    memoize-one: ^5.0.0
+    prop-types: ^15.6.0
+    react-input-autosize: ^3.0.0
+    react-transition-group: ^4.3.0
+  peerDependencies:
+    react: ^16.8.0 || ^17.0.0
+    react-dom: ^16.8.0 || ^17.0.0
+  checksum: e87e0b42a662ddce7957a69a3029ea769b22264c197cbd1d8bde1ce631e49c5c5f42414773364674a7a6a8431340e1ede49220583bf1dcd966b63e9bd25cfc12
+  languageName: node
+  linkType: hard
+
 "react-test-renderer@npm:16.13.0":
   version: 16.13.0
   resolution: "react-test-renderer@npm:16.13.0"
@@ -11643,6 +11807,21 @@ fsevents@~2.3.2:
   languageName: node
   linkType: hard
 
+"react-transition-group@npm:^4.3.0":
+  version: 4.4.2
+  resolution: "react-transition-group@npm:4.4.2"
+  dependencies:
+    "@babel/runtime": ^7.5.5
+    dom-helpers: ^5.0.1
+    loose-envify: ^1.4.0
+    prop-types: ^15.6.2
+  peerDependencies:
+    react: ">=16.6.0"
+    react-dom: ">=16.6.0"
+  checksum: b67bf5b3e86dbab72d658b9a52a3589e5960583ab28c7c66272427d8fe30d4c7de422d5046ae96bd2683cdf80cc3264b2516f5ce80cae1dbe6cf3ca6dda392c5
+  languageName: node
+  linkType: hard
+
 "react-virtualized@npm:9.21.2":
   version: 9.21.2
   resolution: "react-virtualized@npm:9.21.2"
@@ -13227,6 +13406,13 @@ resolve@^1.2.0:
   languageName: node
   linkType: hard
 
+"stylis@npm:^4.0.10":
+  version: 4.0.10
+  resolution: "stylis@npm:4.0.10"
+  checksum: 0fecaf5c234ec3ffcb0afc21478742a815a21cb964365259789be9c1692e72e13d8c081c1150fd76ed2146633a3251cdecd6e0c120b158f44bd74c38f81cafb3
+  languageName: node
+  linkType: hard
+
 "stylus@npm:^0.x":
   version: 0.55.0
   resolution: "stylus@npm:0.55.0"