aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js
diff options
context:
space:
mode:
authorAubert Grégoire <gregaubert@users.noreply.github.com>2017-03-06 14:42:29 +0100
committerGitHub <noreply@github.com>2017-03-06 14:42:29 +0100
commitf3c798e5ec60ba64594a906eaee45d52b7f46f76 (patch)
tree415e4c0579f4c0e2bac7929d1ff0d94003bb71a4 /server/sonar-web/src/main/js
parentacaa082a92df0320ce28553d94d5bdb32ab148e4 (diff)
downloadsonarqube-f3c798e5ec60ba64594a906eaee45d52b7f46f76.tar.gz
sonarqube-f3c798e5ec60ba64594a906eaee45d52b7f46f76.zip
SONAR-8876 Language facet searchbox on projects page (#1741)
Diffstat (limited to 'server/sonar-web/src/main/js')
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/Filter.js13
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/LanguageFilter.js10
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/LanguageFilterFooter.js84
3 files changed, 107 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/Filter.js b/server/sonar-web/src/main/js/apps/projects/filters/Filter.js
index b10b4162d63..53806389065 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/Filter.js
+++ b/server/sonar-web/src/main/js/apps/projects/filters/Filter.js
@@ -33,6 +33,7 @@ export default class Filter extends React.Component {
renderName: React.PropTypes.func.isRequired,
renderOption: React.PropTypes.func.isRequired,
+ renderFooter: React.PropTypes.func,
getFacetValueForOption: React.PropTypes.func,
@@ -130,11 +131,23 @@ export default class Filter extends React.Component {
}
}
+ renderFooter () {
+ if (!this.props.renderFooter) {
+ return null;
+ }
+ return (
+ <div className="search-navigator-facet-footer projects-facet-footer">
+ {this.props.renderFooter()}
+ </div>
+ );
+ }
+
render () {
return (
<div className="search-navigator-facet-box" data-key={this.props.property}>
{this.renderHeader()}
{this.renderOptions()}
+ {this.renderFooter()}
</div>
);
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/LanguageFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/LanguageFilter.js
index 4e3e10921f5..0e3d5e51706 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/LanguageFilter.js
+++ b/server/sonar-web/src/main/js/apps/projects/filters/LanguageFilter.js
@@ -21,6 +21,7 @@ import React from 'react';
import sortBy from 'lodash/sortBy';
import FilterContainer from './FilterContainer';
import LanguageFilterOption from './LanguageFilterOption';
+import LanguageFilterFooter from './LanguageFilterFooter';
export default class LanguageFilter extends React.Component {
static propTypes = {
@@ -39,6 +40,14 @@ export default class LanguageFilter extends React.Component {
return sortBy(Object.keys(facet), [option => -facet[option]]);
}
+ renderFooter = () => (
+ <LanguageFilterFooter
+ property="language"
+ query={this.props.query}
+ isFavorite={this.props.isFavorite}
+ organization={this.props.organization}/>
+ );
+
getFacetValueForOption = (facet, option) => facet[option];
render () {
@@ -48,6 +57,7 @@ export default class LanguageFilter extends React.Component {
getOptions={facet => facet ? this.getSortedOptions(facet) : []}
renderName={() => 'Languages'}
renderOption={this.renderOption}
+ renderFooter={this.renderFooter}
getFacetValueForOption={this.getFacetValueForOption}
query={this.props.query}
isFavorite={this.props.isFavorite}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/LanguageFilterFooter.js b/server/sonar-web/src/main/js/apps/projects/filters/LanguageFilterFooter.js
new file mode 100644
index 00000000000..9db6ebe304f
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projects/filters/LanguageFilterFooter.js
@@ -0,0 +1,84 @@
+/*
+ * 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 { connect } from 'react-redux';
+import { withRouter } from 'react-router';
+import Select from 'react-select';
+import difference from 'lodash/difference';
+import isNil from 'lodash/isNil';
+import omitBy from 'lodash/omitBy';
+import { getProjectsAppFacetByProperty, getLanguages } from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
+
+class LanguageFilterFooter extends React.Component {
+ static propTypes = {
+ property: React.PropTypes.string.isRequired,
+ query: React.PropTypes.object.isRequired,
+ isFavorite: React.PropTypes.bool,
+ organization: React.PropTypes.object,
+ languages: React.PropTypes.object,
+ value: React.PropTypes.any,
+ facet: React.PropTypes.object,
+ getFilterUrl: React.PropTypes.func.isRequired
+ }
+
+ handleLanguageChange = ({ value }) => {
+ const urlOptions = (this.props.value || []).concat(value).join(',');
+ const path = this.props.getFilterUrl({ [this.props.property]: urlOptions });
+ this.props.router.push(path);
+ }
+
+ getOptions () {
+ const { languages, facet } = this.props;
+ let options = Object.keys(languages);
+ if (facet) {
+ options = difference(options, Object.keys(facet));
+ }
+ return options.map(key => ({ label: languages[key].name, value: key }));
+ }
+
+ render () {
+ return (
+ <Select
+ onChange={this.handleLanguageChange}
+ className="input-super-large"
+ options={this.getOptions()}
+ placeholder={translate('search_verb')}
+ clearable={false}
+ searchable={true}/>
+ );
+ }
+}
+
+const mapStateToProps = (state, ownProps) => ({
+ languages: getLanguages(state),
+ value: ownProps.query[ownProps.property],
+ facet: getProjectsAppFacetByProperty(state, ownProps.property),
+ getFilterUrl: part => {
+ const basePathName = ownProps.organization ?
+ `/organizations/${ownProps.organization.key}/projects` :
+ '/projects';
+ const pathname = basePathName + (ownProps.isFavorite ? '/favorite' : '');
+ const query = omitBy({ ...ownProps.query, ...part }, isNil);
+ return { pathname, query };
+ }
+});
+
+export default connect(mapStateToProps)(withRouter(LanguageFilterFooter));