aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/AllProjects.js4
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBar.js42
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBarContainer.js29
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectOptionBar-test.js12
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectOptionBar-test.js.snap15
-rw-r--r--server/sonar-web/src/main/js/apps/projects/styles.css9
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties1
8 files changed, 101 insertions, 13 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js
index f1f83563352..fefc5f19801 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js
@@ -21,7 +21,7 @@
import React from 'react';
import Helmet from 'react-helmet';
import PageHeaderContainer from './PageHeaderContainer';
-import ProjectsOptionBar from './ProjectsOptionBar';
+import ProjectsOptionBarContainer from './ProjectsOptionBarContainer';
import ProjectsListContainer from './ProjectsListContainer';
import ProjectsListFooterContainer from './ProjectsListFooterContainer';
import PageSidebar from './PageSidebar';
@@ -129,7 +129,7 @@ export default class AllProjects extends React.PureComponent {
<div>
<Helmet title={translate('projects.page')} />
- <ProjectsOptionBar
+ <ProjectsOptionBarContainer
onPerspectiveChange={this.handlePerspectiveChange}
onSortChange={this.handleSortChange}
onToggleOptionBar={this.handleOptionBarToggle}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js
index 302ee1941ff..9771b00f497 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js
@@ -54,7 +54,7 @@ export default function PageSidebar({
visualization
}: Props) {
const isFiltered = Object.keys(query)
- .filter(key => key !== 'view' && key !== 'visualization')
+ .filter(key => !['view', 'visualization', 'sort'].includes(key))
.some(key => query[key] != null);
const isLeakView = view === 'leak';
const basePathName = organization ? `/organizations/${organization.key}/projects` : '/projects';
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBar.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBar.js
index e48872ff96e..14a0b01f4b2 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBar.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBar.js
@@ -21,14 +21,18 @@
import React from 'react';
import classNames from 'classnames';
import CloseIcon from '../../../components/icons-components/CloseIcon';
+import Tooltip from '../../../components/controls/Tooltip';
import PerspectiveSelect from './PerspectiveSelect';
import ProjectsSortingSelect from './ProjectsSortingSelect';
+import { translate } from '../../../helpers/l10n';
type Props = {
onPerspectiveChange: ({ view: string, visualization?: string }) => void,
onSortChange: (sort: string, desc: boolean) => void,
onToggleOptionBar: boolean => void,
open: boolean,
+ projects: Array<*>,
+ projectsAppState: { loading: boolean, total?: number },
selectedSort: string,
view: string,
visualization?: string
@@ -43,6 +47,37 @@ export default class ProjectsOptionBar extends React.PureComponent {
this.props.onToggleOptionBar(false);
};
+ renderSortingSelect() {
+ const { projectsAppState, projects, view } = this.props;
+ const limitReached =
+ projects != null &&
+ projectsAppState.total != null &&
+ projects.length < projectsAppState.total;
+
+ if (view === 'visualizations' && !limitReached) {
+ return (
+ <Tooltip overlay={translate('projects.sort.disabled')}>
+ <div>
+ <ProjectsSortingSelect
+ className="projects-topbar-item js-projects-sorting-select disabled"
+ onChange={this.props.onSortChange}
+ selectedSort={this.props.selectedSort}
+ view={this.props.view}
+ />
+ </div>
+ </Tooltip>
+ );
+ }
+ return (
+ <ProjectsSortingSelect
+ className="projects-topbar-item js-projects-sorting-select"
+ onChange={this.props.onSortChange}
+ selectedSort={this.props.selectedSort}
+ view={this.props.view}
+ />
+ );
+ }
+
render() {
const { open } = this.props;
return (
@@ -58,12 +93,7 @@ export default class ProjectsOptionBar extends React.PureComponent {
view={this.props.view}
visualization={this.props.visualization}
/>
- <ProjectsSortingSelect
- className="projects-topbar-item js-projects-sorting-select"
- onChange={this.props.onSortChange}
- selectedSort={this.props.selectedSort}
- view={this.props.view}
- />
+ {this.renderSortingSelect()}
</div>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBarContainer.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBarContainer.js
new file mode 100644
index 00000000000..a58605b2355
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBarContainer.js
@@ -0,0 +1,29 @@
+/*
+ * 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 { connect } from 'react-redux';
+import ProjectsOptionBar from './ProjectsOptionBar';
+import { getProjects, getProjectsAppState } from '../../../store/rootReducer';
+
+const mapStateToProps = state => ({
+ projects: getProjects(state),
+ projectsAppState: getProjectsAppState(state)
+});
+
+export default connect(mapStateToProps)(ProjectsOptionBar);
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectOptionBar-test.js b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectOptionBar-test.js
index 338395a6b84..5b08f5d644e 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectOptionBar-test.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectOptionBar-test.js
@@ -28,11 +28,19 @@ it('should render option bar closed', () => {
it('should render option bar open', () => {
expect(
- shallow(<ProjectsOptionBar open={true} view="leak" visualization="risk" />)
+ shallow(
+ <ProjectsOptionBar
+ open={true}
+ view="leak"
+ visualization="risk"
+ projects={[1, 2, 3]}
+ projectsAppState={{ total: 3 }}
+ />
+ )
).toMatchSnapshot();
});
-it.skip('should not render sorting options for visualizations', () => {
+it('should render disabled sorting options for visualizations', () => {
expect(
shallow(<ProjectsOptionBar open={true} view="visualizations" visualization="coverage" />)
).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectOptionBar-test.js.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectOptionBar-test.js.snap
index 27dff385bd9..5b5ca60dce6 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectOptionBar-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectOptionBar-test.js.snap
@@ -8,7 +8,7 @@ Array [
]
`;
-exports[`should not render sorting options for visualizations 1`] = `
+exports[`should render disabled sorting options for visualizations 1`] = `
<div
className="projects-topbar"
>
@@ -26,10 +26,21 @@ exports[`should not render sorting options for visualizations 1`] = `
className="projects-topbar-actions-inner"
>
<PerspectiveSelect
- className="projects-topbar-item"
+ className="projects-topbar-item js-projects-perspective-select"
view="visualizations"
visualization="coverage"
/>
+ <Tooltip
+ overlay="projects.sort.disabled"
+ placement="bottom"
+ >
+ <div>
+ <ProjectsSortingSelect
+ className="projects-topbar-item js-projects-sorting-select disabled"
+ view="visualizations"
+ />
+ </div>
+ </Tooltip>
</div>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/projects/styles.css b/server/sonar-web/src/main/js/apps/projects/styles.css
index 5bb422126c2..11b1a7b4665 100644
--- a/server/sonar-web/src/main/js/apps/projects/styles.css
+++ b/server/sonar-web/src/main/js/apps/projects/styles.css
@@ -43,6 +43,15 @@
padding: 0 24px;
}
+.projects-topbar-item.disabled {
+ cursor: not-allowed;
+ opacity: 0.4;
+}
+
+.projects-topbar-item.disabled * {
+ pointer-events: none !important;
+}
+
.projects-topbar-button {
box-sizing: border-box;
float: right;
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 2a0e497caa8..7d1f3bb714c 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -910,6 +910,7 @@ projects.facets.quality_gate=Quality Gate
projects.facets.languages=Languages
projects.facets.new_lines=New Lines
projects.facets.tags=Tags
+projects.sort.disabled=Disabled because sorting cannot affect the displayed result with the current project selection.
projects.sort.name=by name
projects.sort.reliability=by reliability (best first)
projects.sort.-reliability=by reliability (worst first)