From: Philippe Perrin Date: Tue, 29 Mar 2022 13:41:18 +0000 (+0200) Subject: SONAR-16091 Update SelectLegacy X-Git-Tag: 9.4.0.54424~24 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1949f6aad24ea81cc3dccaf41953b0809ec69e88;p=sonarqube.git SONAR-16091 Update SelectLegacy --- 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) { /> )} - {translate('status')} - {translate('status')} + props.onFieldChange('key', instance.key)} + components={{ + Option: optionRenderer, + SingleValue: singleValueRenderer + }} + value={instances.filter(instance => instance.key === formData.key)} /> 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 = {}) { return shallow( - @@ -330,19 +334,18 @@ exports[`should render correctly: when there are configuration errors (admin use
-
@@ -472,19 +472,18 @@ exports[`should render correctly: when there are configuration errors (non-admin
-
@@ -617,19 +613,18 @@ exports[`should render correctly: with a single ALM instance 1`] = `
-
@@ -699,19 +691,18 @@ exports[`should render correctly: with a valid and saved form 1`] = `
-
@@ -857,19 +853,18 @@ exports[`should render correctly: with an empty form 1`] = `
-
@@ -949,31 +941,3 @@ exports[`should render correctly: with no ALM instances (non-admin user) 1`] = ` `; - -exports[`should render select options correctly 1`] = ` - - - i1 - — - - - http://github.enterprise.com - - -`; - -exports[`should render select options correctly 2`] = ` - - - i2 - — - - - http://github.enterprise.com - - -`; 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 { - 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 ( - - ); - } -} - -interface OptionProps { - children?: React.ReactNode; - className?: string; - isFocused?: boolean; - onFocus: (option: Option, evt: React.MouseEvent) => void; - onSelect: (option: Option, evt: React.MouseEvent) => void; - option: Option; -} - -export class UsersSelectSearchOption extends React.PureComponent { - handleMouseDown = (evt: React.MouseEvent) => { - evt.preventDefault(); - evt.stopPropagation(); - this.props.onSelect(this.props.option, evt); - }; - - handleMouseEnter = (evt: React.MouseEvent) => { - this.props.onFocus(this.props.option, evt); - }; - - handleMouseMove = (evt: React.MouseEvent) => { - if (this.props.isFocused) { - return; - } - this.props.onFocus(this.props.option, evt); - }; - - render() { - const { option } = this.props; - return ( -
- - {this.props.children} - {option.login} -
- ); - } -} - -interface ValueProps { - value?: Option; - children?: React.ReactNode; -} - -export function UsersSelectSearchValue({ children, value }: ValueProps) { - return ( -
- {value && value.login && ( -
- - {children} - {value.login} -
- )} -
- ); -} 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( - - ); - 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( - - {selectedUser.name} - - ); - expect(wrapper).toMatchSnapshot(); - }); - - it('should render correctly with email instead of hash', () => { - const wrapper = shallow( - - {users[0].name} - - ); - expect(wrapper).toMatchSnapshot(); - }); -}); - -describe('UsersSelectSearchValue', () => { - it('should render correctly with a user', () => { - const wrapper = shallow( - {selectedUser.name} - ); - expect(wrapper).toMatchSnapshot(); - }); - - it('should render correctly with email instead of hash', () => { - const wrapper = shallow( - {users[0].name} - ); - expect(wrapper).toMatchSnapshot(); - }); - - it('should render correctly without value', () => { - const wrapper = shallow(); - 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`] = ` - -`; - -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`] = ` - -`; - -exports[`UsersSelectSearchOption should render correctly with email instead of hash 1`] = ` -
- - - Administrator - - - admin - -
-`; - -exports[`UsersSelectSearchOption should render correctly without all parameters 1`] = ` -
- - - Administrator - - - admin - -
-`; - -exports[`UsersSelectSearchValue should render correctly with a user 1`] = ` -
-
- - - Administrator - - - admin - -
-
-`; - -exports[`UsersSelectSearchValue should render correctly with email instead of hash 1`] = ` -
-
- - - Administrator - - - admin - -
-
-`; - -exports[`UsersSelectSearchValue should render correctly without value 1`] = ` -
-`; diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 8da222bc358..813e85e41ab 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -774,9 +774,11 @@ hotspots.continue_to_next_hotspot=Continue Reviewing hotspot.filters.title=Filters hotspot.filters.assignee.assigned_to_me=Assigned to me hotspot.filters.assignee.all=All +hotspot.filters.status=Status filter hotspot.filters.status.to_review=To review hotspot.filters.status.acknowledged=Acknowledged hotspot.filters.status.fixed=Fixed +hotspot.filters.period=Period filter hotspot.filters.period.since_leak_period=New code hotspot.filters.period.overall=Overall code hotspot.filters.status.safe=Safe