diff options
Diffstat (limited to 'server/sonar-web/src/main/js/apps/projects-admin/search.js')
-rw-r--r-- | server/sonar-web/src/main/js/apps/projects-admin/search.js | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects-admin/search.js b/server/sonar-web/src/main/js/apps/projects-admin/search.js new file mode 100644 index 00000000000..24817c916f9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects-admin/search.js @@ -0,0 +1,159 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 _ from 'underscore'; +import React from 'react'; +import { TYPE, QUALIFIERS_ORDER } from './constants'; +import DeleteView from './delete-view'; +import RadioToggle from '../../components/controls/RadioToggle'; +import Checkbox from '../../components/controls/Checkbox'; +import { translate } from '../../helpers/l10n'; + +export default React.createClass({ + propTypes: { + onSearch: React.PropTypes.func.isRequired + }, + + onSubmit(e) { + e.preventDefault(); + this.search(); + }, + + search() { + const q = this.refs.input.value; + this.props.onSearch(q); + }, + + getTypeOptions() { + return [ + { value: TYPE.ALL, label: 'All' }, + { value: TYPE.PROVISIONED, label: 'Provisioned' }, + { value: TYPE.GHOSTS, label: 'Ghosts' } + ]; + }, + + getQualifierOptions() { + const options = this.props.topLevelQualifiers.map(q => { + return { value: q, label: translate('qualifiers', q) }; + }); + return _.sortBy(options, option => { + return QUALIFIERS_ORDER.indexOf(option.value); + }); + }, + + renderCheckbox() { + const isAllChecked = this.props.projects.length > 0 && + this.props.selection.length === this.props.projects.length; + const thirdState = this.props.projects.length > 0 && + this.props.selection.length > 0 && + this.props.selection.length < this.props.projects.length; + const checked = isAllChecked || thirdState; + return ( + <Checkbox + checked={checked} + thirdState={thirdState} + onCheck={this.onCheck}/> + ); + }, + + renderSpinner() { + return <i className="spinner"/>; + }, + + onCheck(checked) { + if (checked) { + this.props.onAllSelected(); + } else { + this.props.onAllDeselected(); + } + }, + + renderGhostsDescription () { + if (this.props.type !== TYPE.GHOSTS || !this.props.ready) { + return null; + } + return <div className="spacer-top alert alert-info">{translate('bulk_deletion.ghosts.description')}</div>; + }, + + deleteProjects() { + new DeleteView({ + deleteProjects: this.props.deleteProjects + }).render(); + }, + + renderQualifierFilter() { + const options = this.getQualifierOptions(); + if (options.length < 2) { + return null; + } + return ( + <td className="thin nowrap text-middle"> + <RadioToggle + options={this.getQualifierOptions()} + value={this.props.qualifiers} + name="projects-qualifier" + onCheck={this.props.onQualifierChanged}/> + </td> + ); + }, + + render() { + const isSomethingSelected = this.props.projects.length > 0 && this.props.selection.length > 0; + return ( + <div className="panel panel-vertical bordered-bottom spacer-bottom"> + <table className="data"> + <tbody> + <tr> + <td className="thin text-middle"> + {this.props.ready ? this.renderCheckbox() : this.renderSpinner()} + </td> + {this.renderQualifierFilter()} + <td className="thin nowrap text-middle"> + <RadioToggle + options={this.getTypeOptions()} + value={this.props.type} + name="projects-type" + onCheck={this.props.onTypeChanged}/> + </td> + <td className="text-middle"> + <form onSubmit={this.onSubmit} className="search-box"> + <button className="search-box-submit button-clean"> + <i className="icon-search"></i> + </button> + <input onChange={this.search} + value={this.props.query} + ref="input" + className="search-box-input" + type="search" + placeholder="Search"/> + </form> + </td> + <td className="thin text-middle"> + <button onClick={this.deleteProjects} className="button-red" + disabled={!isSomethingSelected}>Delete + </button> + </td> + </tr> + </tbody> + </table> + {this.renderGhostsDescription()} + </div> + ); + } +}); |