aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src
diff options
context:
space:
mode:
authorPhilippe Perrin <philippe.perrin@sonarsource.com>2022-03-29 15:41:18 +0200
committersonartech <sonartech@sonarsource.com>2022-03-30 20:03:10 +0000
commit1949f6aad24ea81cc3dccaf41953b0809ec69e88 (patch)
treed8995b41eb485e7f5cd789216d6c8f5cc1241314 /server/sonar-web/src
parent452e52ba38fb5939ceec03c6591163cc20cb95af (diff)
downloadsonarqube-1949f6aad24ea81cc3dccaf41953b0809ec69e88.tar.gz
sonarqube-1949f6aad24ea81cc3dccaf41953b0809ec69e88.zip
SONAR-16091 Update SelectLegacy
Diffstat (limited to 'server/sonar-web/src')
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx22
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx12
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/FilterBar-test.tsx.snap127
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/Languages.tsx13
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap20
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.tsx13
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx39
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap176
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.tsx197
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/__tests__/UsersSelectSearch-test.tsx96
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearch-test.tsx.snap192
14 files changed, 237 insertions, 698 deletions
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx
index ccbb2979f25..3a7e2733616 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx
@@ -21,7 +21,7 @@ import * as React from 'react';
import withCurrentUserContext from '../../../app/components/current-user/withCurrentUserContext';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import RadioToggle from '../../../components/controls/RadioToggle';
-import SelectLegacy from '../../../components/controls/SelectLegacy';
+import Select from '../../../components/controls/Select';
import Measure from '../../../components/measure/Measure';
import CoverageRating from '../../../components/ui/CoverageRating';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
@@ -43,7 +43,7 @@ export interface FilterBarProps {
onShowAllHotspots: () => void;
}
-const statusOptions: Array<{ label: string; value: string }> = [
+const statusOptions: Array<{ label: string; value: HotspotStatusFilter }> = [
{ value: HotspotStatusFilter.TO_REVIEW, label: translate('hotspot.filters.status.to_review') },
{
value: HotspotStatusFilter.ACKNOWLEDGED,
@@ -111,28 +111,28 @@ export function FilterBar(props: FilterBarProps) {
/>
)}
- <span className="spacer-right">{translate('status')}</span>
- <SelectLegacy
+ <span className="spacer-right"> {translate('status')} </span>
+ <Select
className="input-medium big-spacer-right"
- clearable={false}
+ aria-label={translate('hotspot.filters.status')}
onChange={(option: { value: HotspotStatusFilter }) =>
props.onChangeFilters({ status: option.value })
}
options={statusOptions}
- searchable={false}
- value={filters.status}
+ isSearchable={false}
+ value={statusOptions.find(status => status.value === filters.status)}
/>
{onBranch && (
- <SelectLegacy
+ <Select
className="input-medium big-spacer-right"
- clearable={false}
+ aria-label={translate('hotspot.filters.period')}
onChange={(option: { value: boolean }) =>
props.onChangeFilters({ sinceLeakPeriod: option.value })
}
options={periodOptions}
- searchable={false}
- value={filters.sinceLeakPeriod}
+ isSearchable={false}
+ value={periodOptions.find(period => period.value === filters.sinceLeakPeriod)}
/>
)}
</div>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx
index 91a81f57ebc..1cb08607edc 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx
@@ -20,7 +20,7 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import RadioToggle from '../../../../components/controls/RadioToggle';
-import SelectLegacy from '../../../../components/controls/SelectLegacy';
+import Select from '../../../../components/controls/Select';
import { mockComponent } from '../../../../helpers/mocks/component';
import { mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
import { ComponentQualifier } from '../../../../types/component';
@@ -60,11 +60,11 @@ it('should trigger onChange for status', () => {
const wrapper = shallowRender({ onChangeFilters });
const { onChange } = wrapper
- .find(SelectLegacy)
+ .find(Select)
.at(0)
.props();
- onChange!({ value: HotspotStatusFilter.SAFE });
+ onChange({ value: HotspotStatusFilter.SAFE });
expect(onChangeFilters).toBeCalledWith({ status: HotspotStatusFilter.SAFE });
});
@@ -74,7 +74,7 @@ it('should trigger onChange for self-assigned toggle', () => {
const { onCheck } = wrapper.find(RadioToggle).props();
- onCheck!(AssigneeFilterOption.ALL);
+ onCheck(AssigneeFilterOption.ALL);
expect(onChangeFilters).toBeCalledWith({ assignedToMe: false });
});
@@ -83,11 +83,11 @@ it('should trigger onChange for leak period', () => {
const wrapper = shallowRender({ onChangeFilters });
const { onChange } = wrapper
- .find(SelectLegacy)
+ .find(Select)
.at(1)
.props();
- onChange!({ value: true });
+ onChange({ value: true });
expect(onChangeFilters).toBeCalledWith({ sinceLeakPeriod: true });
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/FilterBar-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/FilterBar-test.tsx.snap
index 89dd2770842..9c037b787b2 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/FilterBar-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/FilterBar-test.tsx.snap
@@ -47,11 +47,14 @@ exports[`should render correctly: anonymous 1`] = `
<span
className="spacer-right"
>
+
status
+
</span>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.status"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -73,12 +76,17 @@ exports[`should render correctly: anonymous 1`] = `
},
]
}
- searchable={false}
- value="TO_REVIEW"
+ value={
+ Object {
+ "label": "hotspot.filters.status.to_review",
+ "value": "TO_REVIEW",
+ }
+ }
/>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.period"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -92,8 +100,12 @@ exports[`should render correctly: anonymous 1`] = `
},
]
}
- searchable={false}
- value={false}
+ value={
+ Object {
+ "label": "hotspot.filters.period.overall",
+ "value": false,
+ }
+ }
/>
</div>
<div
@@ -167,11 +179,14 @@ exports[`should render correctly: logged-in 1`] = `
<span
className="spacer-right"
>
+
status
+
</span>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.status"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -193,12 +208,17 @@ exports[`should render correctly: logged-in 1`] = `
},
]
}
- searchable={false}
- value="TO_REVIEW"
+ value={
+ Object {
+ "label": "hotspot.filters.status.to_review",
+ "value": "TO_REVIEW",
+ }
+ }
/>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.period"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -212,8 +232,12 @@ exports[`should render correctly: logged-in 1`] = `
},
]
}
- searchable={false}
- value={false}
+ value={
+ Object {
+ "label": "hotspot.filters.period.overall",
+ "value": false,
+ }
+ }
/>
</div>
<div
@@ -287,11 +311,14 @@ exports[`should render correctly: non-project 1`] = `
<span
className="spacer-right"
>
+
status
+
</span>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.status"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -313,12 +340,17 @@ exports[`should render correctly: non-project 1`] = `
},
]
}
- searchable={false}
- value="TO_REVIEW"
+ value={
+ Object {
+ "label": "hotspot.filters.status.to_review",
+ "value": "TO_REVIEW",
+ }
+ }
/>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.period"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -332,8 +364,12 @@ exports[`should render correctly: non-project 1`] = `
},
]
}
- searchable={false}
- value={false}
+ value={
+ Object {
+ "label": "hotspot.filters.period.overall",
+ "value": false,
+ }
+ }
/>
</div>
</div>
@@ -366,11 +402,14 @@ exports[`should render correctly: on Pull request 1`] = `
<span
className="spacer-right"
>
+
status
+
</span>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.status"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -392,8 +431,12 @@ exports[`should render correctly: on Pull request 1`] = `
},
]
}
- searchable={false}
- value="TO_REVIEW"
+ value={
+ Object {
+ "label": "hotspot.filters.status.to_review",
+ "value": "TO_REVIEW",
+ }
+ }
/>
</div>
<div
@@ -448,11 +491,14 @@ exports[`should render correctly: with hotspots reviewed measure 1`] = `
<span
className="spacer-right"
>
+
status
+
</span>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.status"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -474,12 +520,17 @@ exports[`should render correctly: with hotspots reviewed measure 1`] = `
},
]
}
- searchable={false}
- value="TO_REVIEW"
+ value={
+ Object {
+ "label": "hotspot.filters.status.to_review",
+ "value": "TO_REVIEW",
+ }
+ }
/>
- <SelectLegacy
+ <Select
+ aria-label="hotspot.filters.period"
className="input-medium big-spacer-right"
- clearable={false}
+ isSearchable={false}
onChange={[Function]}
options={
Array [
@@ -493,8 +544,12 @@ exports[`should render correctly: with hotspots reviewed measure 1`] = `
},
]
}
- searchable={false}
- value={false}
+ value={
+ Object {
+ "label": "hotspot.filters.period.overall",
+ "value": false,
+ }
+ }
/>
</div>
<div
diff --git a/server/sonar-web/src/main/js/apps/settings/components/Languages.tsx b/server/sonar-web/src/main/js/apps/settings/components/Languages.tsx
index 7ffb1d26415..83adcaee686 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/Languages.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/Languages.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import SelectLegacy from '../../../components/controls/SelectLegacy';
+import Select from '../../../components/controls/Select';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
import { translate } from '../../../helpers/l10n';
import { getCategoryName } from '../utils';
@@ -51,14 +51,17 @@ export function Languages(props: LanguagesProps) {
return (
<>
- <h2 className="settings-sub-category-name">{translate('property.category.languages')}</h2>
+ <h2 id="languages-category-title" className="settings-sub-category-name">
+ {translate('property.category.languages')}
+ </h2>
<div data-test="language-select">
- <SelectLegacy
- className="input-large"
+ <Select
+ aria-labelledby="languages-category-title"
+ className="input-large select-settings-language"
onChange={handleOnChange}
options={availableLanguages}
placeholder={translate('settings.languages.select_a_language_placeholder')}
- value={selectedLanguage}
+ value={availableLanguages.find(language => language.value === selectedLanguage)}
/>
</div>
{selectedLanguage && (
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx
index 9e9b03df383..6e44066cdcb 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx
@@ -19,7 +19,7 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import SelectLegacy from '../../../../components/controls/SelectLegacy';
+import Select from '../../../../components/controls/Select';
import { mockComponent } from '../../../../helpers/mocks/component';
import { mockLocation, mockRouter } from '../../../../helpers/testMocks';
import CategoryDefinitionsList from '../CategoryDefinitionsList';
@@ -41,9 +41,9 @@ 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(SelectLegacy).props();
+ const { onChange } = wrapper.find(Select).props();
- onChange!({ label: '', originalValue: 'CoBoL', value: 'cobol' });
+ onChange({ label: '', originalValue: 'CoBoL', value: 'cobol' });
expect(push).toHaveBeenCalledWith(expect.objectContaining({ query: { category: 'CoBoL' } }));
});
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap
index 0659334976a..b44e852341a 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap
@@ -4,14 +4,16 @@ exports[`should render correctly 1`] = `
<Fragment>
<h2
className="settings-sub-category-name"
+ id="languages-category-title"
>
property.category.languages
</h2>
<div
data-test="language-select"
>
- <SelectLegacy
- className="input-large"
+ <Select
+ aria-labelledby="languages-category-title"
+ className="input-large select-settings-language"
onChange={[Function]}
options={
Array [
@@ -33,7 +35,13 @@ exports[`should render correctly 1`] = `
]
}
placeholder="settings.languages.select_a_language_placeholder"
- value="java"
+ value={
+ Object {
+ "label": "property.category.Java",
+ "originalValue": "Java",
+ "value": "java",
+ }
+ }
/>
</div>
<div
@@ -51,14 +59,16 @@ exports[`should render correctly with an unknow language 1`] = `
<Fragment>
<h2
className="settings-sub-category-name"
+ id="languages-category-title"
>
property.category.languages
</h2>
<div
data-test="language-select"
>
- <SelectLegacy
- className="input-large"
+ <Select
+ aria-labelledby="languages-category-title"
+ className="input-large select-settings-language"
onChange={[Function]}
options={
Array [
diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.tsx b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.tsx
index 19285a1f935..6b41d66209b 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import SelectLegacy from '../../../../components/controls/SelectLegacy';
+import Select from '../../../../components/controls/Select';
import { ExtendedSettingDefinition } from '../../../../types/settings';
import { DefaultSpecializedInputProps } from '../../utils';
@@ -30,19 +30,20 @@ export default class InputForSingleSelectList extends React.PureComponent<Props>
};
render() {
- const options = this.props.options.map(option => ({
+ const { options: opts, name, value } = this.props;
+
+ const options = opts.map(option => ({
label: option,
value: option
}));
return (
- <SelectLegacy
+ <Select
className="settings-large-input"
- clearable={false}
- name={this.props.name}
+ name={name}
onChange={this.handleInputChange}
options={options}
- value={this.props.value}
+ value={options.find(option => option.value === value)}
/>
);
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.tsx
index c6a9972e4cf..63172dd9079 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.tsx
@@ -19,17 +19,17 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import SelectLegacy from '../../../../../components/controls/SelectLegacy';
+import Select from '../../../../../components/controls/Select';
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(SelectLegacy);
+ const select = shallowRender({ onChange }).find(Select);
expect(select.length).toBe(1);
expect(select.prop('name')).toBe('foo');
- expect(select.prop('value')).toBe('bar');
+ expect(select.prop('value')).toEqual({ label: 'bar', value: 'bar' });
expect(select.prop('options')).toEqual([
{ value: 'foo', label: 'foo' },
{ value: 'bar', label: 'bar' },
@@ -40,7 +40,7 @@ it('should render Select', () => {
it('should call onChange', () => {
const onChange = jest.fn();
- const select = shallowRender({ onChange }).find(SelectLegacy);
+ const select = shallowRender({ onChange }).find(Select);
expect(select.length).toBe(1);
expect(select.prop('onChange')).toBeDefined();
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx
index 29162ee65e5..b74af2527a5 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx
@@ -20,8 +20,9 @@
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router';
+import { components, OptionProps, SingleValueProps } from 'react-select';
import { Button, SubmitButton } from '../../../../components/controls/buttons';
-import SelectLegacy from '../../../../components/controls/SelectLegacy';
+import Select from '../../../../components/controls/Select';
import AlertSuccessIcon from '../../../../components/icons/AlertSuccessIcon';
import { Alert } from '../../../../components/ui/Alert';
import DeferredSpinner from '../../../../components/ui/DeferredSpinner';
@@ -56,7 +57,15 @@ export interface PRDecorationBindingRendererProps {
isSysAdmin: boolean;
}
-function optionRenderer(instance: AlmSettingsInstance) {
+function optionRenderer(props: OptionProps<AlmSettingsInstance, false>) {
+ return <components.Option {...props}>{customOptions(props.data)}</components.Option>;
+}
+
+function singleValueRenderer(props: SingleValueProps<AlmSettingsInstance>) {
+ return <components.SingleValue {...props}>{customOptions(props.data)}</components.SingleValue>;
+}
+
+function customOptions(instance: AlmSettingsInstance) {
return instance.url ? (
<>
<span>{instance.key} — </span>
@@ -141,22 +150,18 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe
</div>
</div>
<div className="settings-definition-right">
- <SelectLegacy
- autosize={true}
- className="abs-width-400 big-spacer-top"
- clearable={false}
- id="name"
- menuContainerStyle={{
- maxWidth: '210%' /* Allow double the width of the select */,
- width: 'auto'
- }}
- onChange={(instance: AlmSettingsInstance) => props.onFieldChange('key', instance.key)}
- optionRenderer={optionRenderer}
+ <Select
+ inputId="name"
+ className="abs-width-400 big-spacer-top it__configuration-name-select"
+ isClearable={false}
+ isSearchable={false}
options={instances}
- searchable={false}
- value={formData.key}
- valueKey="key"
- valueRenderer={optionRenderer}
+ onChange={(instance: AlmSettingsInstance) => props.onFieldChange('key', instance.key)}
+ components={{
+ Option: optionRenderer,
+ SingleValue: singleValueRenderer
+ }}
+ value={instances.filter(instance => instance.key === formData.key)}
/>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx
index a4bf1454e6d..d61e57e0ea6 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx
@@ -19,8 +19,6 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import SelectLegacy from '../../../../../components/controls/SelectLegacy';
-import { waitAndUpdate } from '../../../../../helpers/testUtils';
import {
AlmKeys,
AlmSettingsInstance,
@@ -124,18 +122,6 @@ it.each([
}
);
-it('should render select options correctly', async () => {
- const wrapper = shallowRender({ instances });
-
- await waitAndUpdate(wrapper);
-
- const { optionRenderer } = wrapper.find(SelectLegacy).props();
-
- expect(optionRenderer!(instances[0])).toMatchSnapshot();
-
- expect(optionRenderer!(instances[1])).toMatchSnapshot();
-});
-
function shallowRender(props: Partial<PRDecorationBindingRendererProps> = {}) {
return shallow(
<PRDecorationBindingRenderer
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap
index f1bf70fdb61..b72c9f4121e 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap
@@ -129,19 +129,18 @@ exports[`should render correctly: when there are configuration errors (admin use
<div
className="settings-definition-right"
>
- <SelectLegacy
- autosize={true}
- className="abs-width-400 big-spacer-top"
- clearable={false}
- id="name"
- menuContainerStyle={
+ <Select
+ className="abs-width-400 big-spacer-top it__configuration-name-select"
+ components={
Object {
- "maxWidth": "210%",
- "width": "auto",
+ "Option": [Function],
+ "SingleValue": [Function],
}
}
+ inputId="name"
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionRenderer={[Function]}
options={
Array [
Object {
@@ -165,10 +164,15 @@ exports[`should render correctly: when there are configuration errors (admin use
},
]
}
- searchable={false}
- value="i1"
- valueKey="key"
- valueRenderer={[Function]}
+ value={
+ Array [
+ Object {
+ "alm": "github",
+ "key": "i1",
+ "url": "http://github.enterprise.com",
+ },
+ ]
+ }
/>
</div>
</div>
@@ -330,19 +334,18 @@ exports[`should render correctly: when there are configuration errors (admin use
<div
className="settings-definition-right"
>
- <SelectLegacy
- autosize={true}
- className="abs-width-400 big-spacer-top"
- clearable={false}
- id="name"
- menuContainerStyle={
+ <Select
+ className="abs-width-400 big-spacer-top it__configuration-name-select"
+ components={
Object {
- "maxWidth": "210%",
- "width": "auto",
+ "Option": [Function],
+ "SingleValue": [Function],
}
}
+ inputId="name"
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionRenderer={[Function]}
options={
Array [
Object {
@@ -366,10 +369,7 @@ exports[`should render correctly: when there are configuration errors (admin use
},
]
}
- searchable={false}
- value=""
- valueKey="key"
- valueRenderer={[Function]}
+ value={Array []}
/>
</div>
</div>
@@ -472,19 +472,18 @@ exports[`should render correctly: when there are configuration errors (non-admin
<div
className="settings-definition-right"
>
- <SelectLegacy
- autosize={true}
- className="abs-width-400 big-spacer-top"
- clearable={false}
- id="name"
- menuContainerStyle={
+ <Select
+ className="abs-width-400 big-spacer-top it__configuration-name-select"
+ components={
Object {
- "maxWidth": "210%",
- "width": "auto",
+ "Option": [Function],
+ "SingleValue": [Function],
}
}
+ inputId="name"
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionRenderer={[Function]}
options={
Array [
Object {
@@ -508,10 +507,7 @@ exports[`should render correctly: when there are configuration errors (non-admin
},
]
}
- searchable={false}
- value=""
- valueKey="key"
- valueRenderer={[Function]}
+ value={Array []}
/>
</div>
</div>
@@ -617,19 +613,18 @@ exports[`should render correctly: with a single ALM instance 1`] = `
<div
className="settings-definition-right"
>
- <SelectLegacy
- autosize={true}
- className="abs-width-400 big-spacer-top"
- clearable={false}
- id="name"
- menuContainerStyle={
+ <Select
+ className="abs-width-400 big-spacer-top it__configuration-name-select"
+ components={
Object {
- "maxWidth": "210%",
- "width": "auto",
+ "Option": [Function],
+ "SingleValue": [Function],
}
}
+ inputId="name"
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionRenderer={[Function]}
options={
Array [
Object {
@@ -639,10 +634,7 @@ exports[`should render correctly: with a single ALM instance 1`] = `
},
]
}
- searchable={false}
- value=""
- valueKey="key"
- valueRenderer={[Function]}
+ value={Array []}
/>
</div>
</div>
@@ -699,19 +691,18 @@ exports[`should render correctly: with a valid and saved form 1`] = `
<div
className="settings-definition-right"
>
- <SelectLegacy
- autosize={true}
- className="abs-width-400 big-spacer-top"
- clearable={false}
- id="name"
- menuContainerStyle={
+ <Select
+ className="abs-width-400 big-spacer-top it__configuration-name-select"
+ components={
Object {
- "maxWidth": "210%",
- "width": "auto",
+ "Option": [Function],
+ "SingleValue": [Function],
}
}
+ inputId="name"
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionRenderer={[Function]}
options={
Array [
Object {
@@ -735,10 +726,15 @@ exports[`should render correctly: with a valid and saved form 1`] = `
},
]
}
- searchable={false}
- value="i1"
- valueKey="key"
- valueRenderer={[Function]}
+ value={
+ Array [
+ Object {
+ "alm": "github",
+ "key": "i1",
+ "url": "http://github.enterprise.com",
+ },
+ ]
+ }
/>
</div>
</div>
@@ -857,19 +853,18 @@ exports[`should render correctly: with an empty form 1`] = `
<div
className="settings-definition-right"
>
- <SelectLegacy
- autosize={true}
- className="abs-width-400 big-spacer-top"
- clearable={false}
- id="name"
- menuContainerStyle={
+ <Select
+ className="abs-width-400 big-spacer-top it__configuration-name-select"
+ components={
Object {
- "maxWidth": "210%",
- "width": "auto",
+ "Option": [Function],
+ "SingleValue": [Function],
}
}
+ inputId="name"
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionRenderer={[Function]}
options={
Array [
Object {
@@ -893,10 +888,7 @@ exports[`should render correctly: with an empty form 1`] = `
},
]
}
- searchable={false}
- value=""
- valueKey="key"
- valueRenderer={[Function]}
+ value={Array []}
/>
</div>
</div>
@@ -949,31 +941,3 @@ exports[`should render correctly: with no ALM instances (non-admin user) 1`] = `
</Alert>
</div>
`;
-
-exports[`should render select options correctly 1`] = `
-<React.Fragment>
- <span>
- i1
- —
- </span>
- <span
- className="text-muted"
- >
- http://github.enterprise.com
- </span>
-</React.Fragment>
-`;
-
-exports[`should render select options correctly 2`] = `
-<React.Fragment>
- <span>
- i2
- —
- </span>
- <span
- className="text-muted"
- >
- http://github.enterprise.com
- </span>
-</React.Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.tsx b/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.tsx
deleted file mode 100644
index 6b6cca17385..00000000000
--- a/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.tsx
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { debounce } from 'lodash';
-import * as React from 'react';
-import SelectLegacy from '../../../components/controls/SelectLegacy';
-import Avatar from '../../../components/ui/Avatar';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-
-interface Option {
- login: string;
- name: string;
- avatar?: string;
-}
-
-interface Props {
- autoFocus?: boolean;
- excludedUsers: string[];
- handleValueChange: (option: Option) => void;
- searchUsers: (query: string, ps: number) => Promise<{ users: Option[] }>;
- selectedUser?: Option;
-}
-
-interface State {
- isLoading: boolean;
- search: string;
- searchResult: Option[];
-}
-
-const LIST_SIZE = 10;
-const AVATAR_SIZE = 16;
-
-export default class UsersSelectSearch extends React.PureComponent<Props, State> {
- mounted = false;
-
- constructor(props: Props) {
- super(props);
- this.handleSearch = debounce(this.handleSearch, 250);
- this.state = { searchResult: [], isLoading: false, search: '' };
- }
-
- componentDidMount() {
- this.mounted = true;
- this.handleSearch(this.state.search);
- }
-
- componentDidUpdate(prevProps: Props) {
- if (this.props.excludedUsers !== prevProps.excludedUsers) {
- this.handleSearch(this.state.search);
- }
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- filterSearchResult = ({ users }: { users: Option[] }) =>
- users.filter(user => !this.props.excludedUsers.includes(user.login)).slice(0, LIST_SIZE);
-
- filterOptions = (options: Option[]) => {
- return options; // We don't filter anything, this is done by the WS
- };
-
- handleSearch = (search: string) => {
- this.props
- .searchUsers(search, Math.min(this.props.excludedUsers.length + LIST_SIZE, 500))
- .then(this.filterSearchResult)
- .then(
- searchResult => {
- if (this.mounted) {
- this.setState({ isLoading: false, searchResult });
- }
- },
- () => {
- if (this.mounted) {
- this.setState({ isLoading: false, searchResult: [] });
- }
- }
- );
- };
-
- handleInputChange = (search: string) => {
- if (search == null || search.length === 1) {
- this.setState({ search });
- } else {
- this.setState({ isLoading: true, search });
- this.handleSearch(search);
- }
- };
-
- render() {
- const noResult =
- this.state.search.length === 1
- ? translateWithParameters('select2.tooShort', 2)
- : translate('no_results');
- return (
- <SelectLegacy
- autoFocus={this.props.autoFocus}
- className="Select-big"
- clearable={false}
- filterOptions={this.filterOptions}
- isLoading={this.state.isLoading}
- labelKey="name"
- noResultsText={noResult}
- onChange={this.props.handleValueChange}
- onInputChange={this.handleInputChange}
- optionComponent={UsersSelectSearchOption}
- options={this.state.searchResult}
- placeholder=""
- searchable={true}
- value={this.props.selectedUser}
- valueComponent={UsersSelectSearchValue}
- valueKey="login"
- />
- );
- }
-}
-
-interface OptionProps {
- children?: React.ReactNode;
- className?: string;
- isFocused?: boolean;
- onFocus: (option: Option, evt: React.MouseEvent<HTMLDivElement>) => void;
- onSelect: (option: Option, evt: React.MouseEvent<HTMLDivElement>) => void;
- option: Option;
-}
-
-export class UsersSelectSearchOption extends React.PureComponent<OptionProps> {
- handleMouseDown = (evt: React.MouseEvent<HTMLDivElement>) => {
- evt.preventDefault();
- evt.stopPropagation();
- this.props.onSelect(this.props.option, evt);
- };
-
- handleMouseEnter = (evt: React.MouseEvent<HTMLDivElement>) => {
- this.props.onFocus(this.props.option, evt);
- };
-
- handleMouseMove = (evt: React.MouseEvent<HTMLDivElement>) => {
- if (this.props.isFocused) {
- return;
- }
- this.props.onFocus(this.props.option, evt);
- };
-
- render() {
- const { option } = this.props;
- return (
- <div
- className={this.props.className}
- onMouseDown={this.handleMouseDown}
- onMouseEnter={this.handleMouseEnter}
- onMouseMove={this.handleMouseMove}
- role="listitem"
- title={option.name}>
- <Avatar hash={option.avatar} name={option.name} size={AVATAR_SIZE} />
- <strong className="spacer-left">{this.props.children}</strong>
- <span className="note little-spacer-left">{option.login}</span>
- </div>
- );
- }
-}
-
-interface ValueProps {
- value?: Option;
- children?: React.ReactNode;
-}
-
-export function UsersSelectSearchValue({ children, value }: ValueProps) {
- return (
- <div className="Select-value" title={value ? value.name : ''}>
- {value && value.login && (
- <div className="Select-value-label">
- <Avatar hash={value.avatar} name={value.name} size={AVATAR_SIZE} />
- <strong className="spacer-left">{children}</strong>
- <span className="note little-spacer-left">{value.login}</span>
- </div>
- )}
- </div>
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/users/components/__tests__/UsersSelectSearch-test.tsx b/server/sonar-web/src/main/js/apps/users/components/__tests__/UsersSelectSearch-test.tsx
deleted file mode 100644
index d1d2c35b689..00000000000
--- a/server/sonar-web/src/main/js/apps/users/components/__tests__/UsersSelectSearch-test.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import UsersSelectSearch, {
- UsersSelectSearchOption,
- UsersSelectSearchValue
-} from '../UsersSelectSearch';
-
-const selectedUser = {
- login: 'admin',
- name: 'Administrator',
- avatar: '7daf6c79d4802916d83f6266e24850af'
-};
-const users = [
- { login: 'admin', name: 'Administrator', email: 'admin@admin.ch' },
- { login: 'test', name: 'Tester', email: 'tester@testing.ch' },
- { login: 'foo', name: 'Foo Bar', email: 'foo@bar.ch' }
-];
-const excludedUsers = ['admin'];
-
-describe('UsersSelectSearch', () => {
- it('should render correctly', () => {
- const onSearch = jest.fn().mockResolvedValue({ users });
- const wrapper = shallow(
- <UsersSelectSearch
- excludedUsers={excludedUsers}
- handleValueChange={jest.fn()}
- searchUsers={onSearch}
- selectedUser={selectedUser}
- />
- );
- expect(wrapper).toMatchSnapshot();
- const searchResult = (wrapper.instance() as UsersSelectSearch).filterSearchResult({ users });
- expect(searchResult).toMatchSnapshot();
- expect(wrapper.setState({ searchResult })).toMatchSnapshot();
- });
-});
-
-describe('UsersSelectSearchOption', () => {
- it('should render correctly without all parameters', () => {
- const wrapper = shallow(
- <UsersSelectSearchOption onFocus={jest.fn()} onSelect={jest.fn()} option={selectedUser}>
- {selectedUser.name}
- </UsersSelectSearchOption>
- );
- expect(wrapper).toMatchSnapshot();
- });
-
- it('should render correctly with email instead of hash', () => {
- const wrapper = shallow(
- <UsersSelectSearchOption onFocus={jest.fn()} onSelect={jest.fn()} option={users[0]}>
- {users[0].name}
- </UsersSelectSearchOption>
- );
- expect(wrapper).toMatchSnapshot();
- });
-});
-
-describe('UsersSelectSearchValue', () => {
- it('should render correctly with a user', () => {
- const wrapper = shallow(
- <UsersSelectSearchValue value={selectedUser}>{selectedUser.name}</UsersSelectSearchValue>
- );
- expect(wrapper).toMatchSnapshot();
- });
-
- it('should render correctly with email instead of hash', () => {
- const wrapper = shallow(
- <UsersSelectSearchValue value={users[0]}>{users[0].name}</UsersSelectSearchValue>
- );
- expect(wrapper).toMatchSnapshot();
- });
-
- it('should render correctly without value', () => {
- const wrapper = shallow(<UsersSelectSearchValue />);
- expect(wrapper).toMatchSnapshot();
- });
-});
diff --git a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearch-test.tsx.snap b/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearch-test.tsx.snap
deleted file mode 100644
index 0d6493812cf..00000000000
--- a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearch-test.tsx.snap
+++ /dev/null
@@ -1,192 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`UsersSelectSearch should render correctly 1`] = `
-<SelectLegacy
- className="Select-big"
- clearable={false}
- filterOptions={[Function]}
- isLoading={false}
- labelKey="name"
- noResultsText="no_results"
- onChange={[MockFunction]}
- onInputChange={[Function]}
- optionComponent={[Function]}
- options={Array []}
- placeholder=""
- searchable={true}
- value={
- Object {
- "avatar": "7daf6c79d4802916d83f6266e24850af",
- "login": "admin",
- "name": "Administrator",
- }
- }
- valueComponent={[Function]}
- valueKey="login"
-/>
-`;
-
-exports[`UsersSelectSearch should render correctly 2`] = `
-Array [
- Object {
- "email": "tester@testing.ch",
- "login": "test",
- "name": "Tester",
- },
- Object {
- "email": "foo@bar.ch",
- "login": "foo",
- "name": "Foo Bar",
- },
-]
-`;
-
-exports[`UsersSelectSearch should render correctly 3`] = `
-<SelectLegacy
- className="Select-big"
- clearable={false}
- filterOptions={[Function]}
- isLoading={false}
- labelKey="name"
- noResultsText="no_results"
- onChange={[MockFunction]}
- onInputChange={[Function]}
- optionComponent={[Function]}
- options={
- Array [
- Object {
- "email": "tester@testing.ch",
- "login": "test",
- "name": "Tester",
- },
- Object {
- "email": "foo@bar.ch",
- "login": "foo",
- "name": "Foo Bar",
- },
- ]
- }
- placeholder=""
- searchable={true}
- value={
- Object {
- "avatar": "7daf6c79d4802916d83f6266e24850af",
- "login": "admin",
- "name": "Administrator",
- }
- }
- valueComponent={[Function]}
- valueKey="login"
-/>
-`;
-
-exports[`UsersSelectSearchOption should render correctly with email instead of hash 1`] = `
-<div
- onMouseDown={[Function]}
- onMouseEnter={[Function]}
- onMouseMove={[Function]}
- role="listitem"
- title="Administrator"
->
- <withAppStateContext(Avatar)
- name="Administrator"
- size={16}
- />
- <strong
- className="spacer-left"
- >
- Administrator
- </strong>
- <span
- className="note little-spacer-left"
- >
- admin
- </span>
-</div>
-`;
-
-exports[`UsersSelectSearchOption should render correctly without all parameters 1`] = `
-<div
- onMouseDown={[Function]}
- onMouseEnter={[Function]}
- onMouseMove={[Function]}
- role="listitem"
- title="Administrator"
->
- <withAppStateContext(Avatar)
- hash="7daf6c79d4802916d83f6266e24850af"
- name="Administrator"
- size={16}
- />
- <strong
- className="spacer-left"
- >
- Administrator
- </strong>
- <span
- className="note little-spacer-left"
- >
- admin
- </span>
-</div>
-`;
-
-exports[`UsersSelectSearchValue should render correctly with a user 1`] = `
-<div
- className="Select-value"
- title="Administrator"
->
- <div
- className="Select-value-label"
- >
- <withAppStateContext(Avatar)
- hash="7daf6c79d4802916d83f6266e24850af"
- name="Administrator"
- size={16}
- />
- <strong
- className="spacer-left"
- >
- Administrator
- </strong>
- <span
- className="note little-spacer-left"
- >
- admin
- </span>
- </div>
-</div>
-`;
-
-exports[`UsersSelectSearchValue should render correctly with email instead of hash 1`] = `
-<div
- className="Select-value"
- title="Administrator"
->
- <div
- className="Select-value-label"
- >
- <withAppStateContext(Avatar)
- name="Administrator"
- size={16}
- />
- <strong
- className="spacer-left"
- >
- Administrator
- </strong>
- <span
- className="note little-spacer-left"
- >
- admin
- </span>
- </div>
-</div>
-`;
-
-exports[`UsersSelectSearchValue should render correctly without value 1`] = `
-<div
- className="Select-value"
- title=""
-/>
-`;