diff options
Diffstat (limited to 'server/sonar-web/src/main/js/apps/users')
6 files changed, 28 insertions, 209 deletions
diff --git a/server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js b/server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js index 70b309109d0..3e6bbd28b32 100644 --- a/server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js +++ b/server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js @@ -26,6 +26,7 @@ import { getCurrentUser } from '../../../store/rootReducer'; import { translate } from '../../../helpers/l10n'; // import styles to have the `.button-icon` styles import '../../../components/ui/buttons.css'; +import '../../../components/controls/SearchBox.css'; class UsersAppContainer extends React.PureComponent { static propTypes = { diff --git a/server/sonar-web/src/main/js/apps/users/components/UsersSearch.js b/server/sonar-web/src/main/js/apps/users/components/UsersSearch.js deleted file mode 100644 index 32916a9f8ac..00000000000 --- a/server/sonar-web/src/main/js/apps/users/components/UsersSearch.js +++ /dev/null @@ -1,87 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 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. - */ -//@flow -import React from 'react'; -import { debounce } from 'lodash'; -import classNames from 'classnames'; -import { translate, translateWithParameters } from '../../../helpers/l10n'; - -/*:: -type Props = { - onSearch: (query?: string) => void, - className?: string -}; -*/ - -/*:: -type State = { - query?: string -}; -*/ - -export default class UsersSearch extends React.PureComponent { - /*:: props: Props; */ - /*:: state: State; */ - - constructor(props /*: Props */) { - super(props); - this.state = { - query: '' - }; - this.handleSearch = debounce(this.handleSearch, 250); - } - - handleSearch = (query /*: string */) => { - this.props.onSearch(query); - }; - - handleInputChange = ({ target } /*: { target: HTMLInputElement } */) => { - this.setState({ query: target.value }); - if (!target.value || target.value.length >= 2) { - this.handleSearch(target.value); - } - }; - - render() { - const { query } = this.state; - const searchBoxClass = classNames('search-box', this.props.className); - const inputClassName = classNames('search-box-input', { - touched: query != null && query.length === 1 - }); - return ( - <div className={searchBoxClass}> - <button className="search-box-submit button-clean"> - <i className="icon-search" /> - </button> - <input - type="search" - value={query} - className={inputClassName} - placeholder={translate('search_verb')} - onChange={this.handleInputChange} - autoComplete="off" - /> - <span className="note spacer-left text-middle"> - {translateWithParameters('select2.tooShort', 2)} - </span> - </div> - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/users/components/__tests__/UserSearch-test.js b/server/sonar-web/src/main/js/apps/users/components/__tests__/UserSearch-test.js deleted file mode 100644 index 71fd3cc465e..00000000000 --- a/server/sonar-web/src/main/js/apps/users/components/__tests__/UserSearch-test.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 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 React from 'react'; -import { shallow } from 'enzyme'; -import UsersSearch from '../UsersSearch'; - -it('should render correctly', () => { - const wrapper = shallow(<UsersSearch onSearch={jest.fn()} className="test" />); - expect(wrapper).toMatchSnapshot(); - wrapper.setState({ query: 'foo' }); - expect(wrapper).toMatchSnapshot(); -}); - -it('should display a help message when there is less than 2 characters', () => { - const wrapper = shallow(<UsersSearch onSearch={jest.fn()} />); - wrapper.setState({ query: 'f' }); - expect(wrapper).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UserSearch-test.js.snap b/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UserSearch-test.js.snap deleted file mode 100644 index de9d0313c54..00000000000 --- a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UserSearch-test.js.snap +++ /dev/null @@ -1,82 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should display a help message when there is less than 2 characters 1`] = ` -<div - className="search-box" -> - <button - className="search-box-submit button-clean" - > - <i - className="icon-search" - /> - </button> - <input - autoComplete="off" - className="search-box-input touched" - onChange={[Function]} - placeholder="search_verb" - type="search" - value="f" - /> - <span - className="note spacer-left text-middle" - > - select2.tooShort.2 - </span> -</div> -`; - -exports[`should render correctly 1`] = ` -<div - className="search-box test" -> - <button - className="search-box-submit button-clean" - > - <i - className="icon-search" - /> - </button> - <input - autoComplete="off" - className="search-box-input" - onChange={[Function]} - placeholder="search_verb" - type="search" - value="" - /> - <span - className="note spacer-left text-middle" - > - select2.tooShort.2 - </span> -</div> -`; - -exports[`should render correctly 2`] = ` -<div - className="search-box test" -> - <button - className="search-box-submit button-clean" - > - <i - className="icon-search" - /> - </button> - <input - autoComplete="off" - className="search-box-input" - onChange={[Function]} - placeholder="search_verb" - type="search" - value="foo" - /> - <span - className="note spacer-left text-middle" - > - select2.tooShort.2 - </span> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/users/search-view.js b/server/sonar-web/src/main/js/apps/users/search-view.js index a0f52d20cac..f7afc9e81aa 100644 --- a/server/sonar-web/src/main/js/apps/users/search-view.js +++ b/server/sonar-web/src/main/js/apps/users/search-view.js @@ -25,13 +25,15 @@ export default Marionette.ItemView.extend({ template: Template, ui: { - hint: '.js-hint' + hint: '.js-hint', + reset: '.js-reset' }, events: { 'submit #users-search-form': 'onFormSubmit', 'search #users-search-query': 'initialOnKeyUp', - 'keyup #users-search-query': 'initialOnKeyUp' + 'keyup #users-search-query': 'initialOnKeyUp', + 'click .js-reset': 'onResetClick' }, initialize() { @@ -51,6 +53,7 @@ export default Marionette.ItemView.extend({ initialOnKeyUp() { const q = this.getQuery(); this.ui.hint.toggleClass('hidden', q.length !== 1); + this.ui.reset.toggleClass('hidden', q.length === 0); this.debouncedOnKeyUp(); }, @@ -64,6 +67,7 @@ export default Marionette.ItemView.extend({ this.searchRequest.abort(); } this.ui.hint.toggleClass('hidden', q.length !== 1); + this.ui.reset.toggleClass('hidden', q.length === 0); if (q.length !== 1) { this.searchRequest = this.search(q); } @@ -75,5 +79,14 @@ export default Marionette.ItemView.extend({ search(q) { return this.collection.fetch({ reset: true, data: { q } }); + }, + + onResetClick(e) { + e.preventDefault(); + e.currentTarget.blur(); + this.$('#users-search-query') + .val('') + .focus(); + this.onKeyUp(); } }); diff --git a/server/sonar-web/src/main/js/apps/users/templates/users-search.hbs b/server/sonar-web/src/main/js/apps/users/templates/users-search.hbs index 4b879a050ba..a95ed5eb718 100644 --- a/server/sonar-web/src/main/js/apps/users/templates/users-search.hbs +++ b/server/sonar-web/src/main/js/apps/users/templates/users-search.hbs @@ -1,8 +1,17 @@ <div class="panel panel-vertical bordered-bottom spacer-bottom"> <form id="users-search-form" class="search-box"> - <button id="users-search-submit" class="search-box-submit button-clean"><i class="icon-search"></i></button> - <input id="users-search-query" class="search-box-input" type="search" name="q" placeholder="{{t 'search_verb'}}" maxlength="100"> - <span class="js-hint note spacer-left text-middle hidden"> + <input id="users-search-query" class="search-box-input" type="text" name="q" placeholder="{{t 'search.search_by_login_or_name'}}" maxlength="100"> + <svg class="search-box-magnifier" width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"> + <g transform="matrix(0.0288462,0,0,0.0288462,2,1.07692)"> + <path d="M288,208C288,177.167 277.042,150.792 255.125,128.875C233.208,106.958 206.833,96 176,96C145.167,96 118.792,106.958 96.875,128.875C74.958,150.792 64,177.167 64,208C64,238.833 74.958,265.208 96.875,287.125C118.792,309.042 145.167,320 176,320C206.833,320 233.208,309.042 255.125,287.125C277.042,265.208 288,238.833 288,208ZM416,416C416,424.667 412.833,432.167 406.5,438.5C400.167,444.833 392.667,448 384,448C375,448 367.5,444.833 361.5,438.5L275.75,353C245.917,373.667 212.667,384 176,384C152.167,384 129.375,379.375 107.625,370.125C85.875,360.875 67.125,348.375 51.375,332.625C35.625,316.875 23.125,298.125 13.875,276.375C4.625,254.625 0,231.833 0,208C0,184.167 4.625,161.375 13.875,139.625C23.125,117.875 35.625,99.125 51.375,83.375C67.125,67.625 85.875,55.125 107.625,45.875C129.375,36.625 152.167,32 176,32C199.833,32 222.625,36.625 244.375,45.875C266.125,55.125 284.875,67.625 300.625,83.375C316.375,99.125 328.875,117.875 338.125,139.625C347.375,161.375 352,184.167 352,208C352,244.667 341.667,277.917 321,307.75L406.75,393.5C412.917,399.667 416,407.167 416,416Z" style="fill:currentColor;fill-rule:nonzero;"/> + </g> + </svg> + <button class="js-reset hidden button-tiny search-box-clear button-icon" style="color: rgb(153, 153, 153);" type="reset"> + <svg width="12" height="12" viewBox="0 0 16 16" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"> + <path d="M14 4.242L11.758 2l-3.76 3.76L4.242 2 2 4.242l3.756 3.756L2 11.758 4.242 14l3.756-3.76 3.76 3.76L14 11.758l-3.76-3.76L14 4.242z" style="fill: currentcolor;"/> + </svg> + </button> + <span class="js-hint search-box-note hidden" title="{{tp 'select2.tooShort' 2}}"> {{tp 'select2.tooShort' 2}} </span> </form> |