aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-06-07 08:52:06 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-06-09 08:26:48 +0200
commit8f72ff71176bc374f649e779bbe8c22833c0e39c (patch)
tree62464afeee7a02fbf1d35d7765c85ffda7c89a3f /server/sonar-web/src/main/js
parentdb6fc1233cfe6d281c1bbee419d4cfdff6b02561 (diff)
downloadsonarqube-8f72ff71176bc374f649e779bbe8c22833c0e39c.tar.gz
sonarqube-8f72ff71176bc374f649e779bbe8c22833c0e39c.zip
SONAR-9245 Update sorting select for leak in projects page
Diffstat (limited to 'server/sonar-web/src/main/js')
-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/ProjectsOptionBar.js7
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelect.js21
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelectOption.js7
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectOptionBar-test.js24
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelect-test.js16
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectOptionBar-test.js.snap19
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelect-test.js.snap84
-rw-r--r--server/sonar-web/src/main/js/apps/projects/styles.css8
-rw-r--r--server/sonar-web/src/main/js/apps/projects/utils.js12
10 files changed, 124 insertions, 78 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 3adb8c5e0e8..dd440f83927 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
@@ -38,7 +38,8 @@ type Props = {
optionBarOpen: boolean,
optionBarToggle: (open: boolean) => void,
organization?: { key: string },
- router: { push: ({ pathname: string, query?: {} }) => void }
+ router: { push: ({ pathname: string, query?: {} }) => void },
+ user?: { isLoggedIn: boolean }
};
type State = {
@@ -132,6 +133,7 @@ export default class AllProjects extends React.PureComponent {
onToggleOptionBar={this.props.optionBarToggle}
open={optionBarOpen}
selectedSort={selectedSort}
+ user={this.props.user}
view={view}
visualization={visualization}
/>
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 ada472b4beb..b076abcb98d 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
@@ -33,6 +33,7 @@ type Props = {
projects: Array<*>,
projectsAppState: { loading: boolean, total?: number },
selectedSort: string,
+ user?: { isLoggedIn: boolean },
view: string,
visualization?: string
};
@@ -47,18 +48,19 @@ export default class ProjectsOptionBar extends React.PureComponent {
};
renderSortingSelect() {
- const { projectsAppState, projects, view } = this.props;
+ const { projectsAppState, projects, user, view } = this.props;
const limitReached =
projects != null &&
projectsAppState.total != null &&
projects.length < projectsAppState.total;
-
+ const defaultOption = user && user.isLoggedIn ? 'name' : 'analysis_date';
if (view === 'visualizations' && !limitReached) {
return (
<Tooltip overlay={translate('projects.sort.disabled')}>
<div>
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select disabled"
+ defaultOption={defaultOption}
onChange={this.props.onSortChange}
selectedSort={this.props.selectedSort}
view={this.props.view}
@@ -70,6 +72,7 @@ export default class ProjectsOptionBar extends React.PureComponent {
return (
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select"
+ defaultOption={defaultOption}
onChange={this.props.onSortChange}
selectedSort={this.props.selectedSort}
view={this.props.view}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelect.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelect.js
index 4a5556bd91d..51d6f1fdd5e 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelect.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelect.js
@@ -19,6 +19,7 @@
*/
// @flow
import React from 'react';
+import { sortBy } from 'lodash';
import Select from 'react-select';
import ProjectsSortingSelectOption from './ProjectsSortingSelectOption';
import SortAscIcon from '../../../components/icons-components/SortAscIcon';
@@ -27,13 +28,14 @@ import Tooltip from '../../../components/controls/Tooltip';
import { translate } from '../../../helpers/l10n';
import { SORTING_METRICS, SORTING_LEAK_METRICS, parseSorting } from '../utils';
-export type Option = { label: string, value: string, complement?: string, short?: string };
+export type Option = { label: string, value: string, class?: string, short?: string };
type Props = {
className?: string,
onChange: (sort: string, desc: boolean) => void,
selectedSort: string,
- view: string
+ view: string,
+ defaultOption: string
};
type State = {
@@ -58,11 +60,16 @@ export default class ProjectsSortingSelect extends React.PureComponent {
getOptions = () => {
const sortMetrics = this.props.view === 'leak' ? SORTING_LEAK_METRICS : SORTING_METRICS;
- return sortMetrics.map((opt: { value: string, complement?: string }) => ({
+ return sortBy(
+ sortMetrics,
+ opt => (opt.value === this.props.defaultOption ? 0 : 1)
+ ).map((opt: { value: string, class?: string }) => ({
value: opt.value,
- label: translate('projects.sorting', opt.value),
- complement: opt.complement && translate('projects.sorting', opt.complement),
- short: opt.complement && translate('projects.sorting', opt.value, 'short')
+ label: translate('projects.sorting', opt.value) +
+ (opt.value === this.props.defaultOption
+ ? ` (${translate('projects.sorting.default')})`
+ : ''),
+ class: opt.class
}));
};
@@ -84,8 +91,8 @@ export default class ProjectsSortingSelect extends React.PureComponent {
className="little-spacer-left input-large"
clearable={false}
onChange={this.handleSortChange}
- options={this.getOptions()}
optionComponent={ProjectsSortingSelectOption}
+ options={this.getOptions()}
searchable={false}
value={this.state.sortValue}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelectOption.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelectOption.js
index f3613f1153e..9789a3d30fb 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelectOption.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsSortingSelectOption.js
@@ -19,6 +19,7 @@
*/
//@flow
import React from 'react';
+import classNames from 'classnames';
import type { Option } from './ProjectsSortingSelect';
type Props = {
@@ -54,16 +55,12 @@ export default class ProjectsSortingSelectOption extends React.PureComponent {
const { option } = this.props;
return (
<div
- className={this.props.className}
+ className={classNames(this.props.className, option.class)}
onMouseDown={this.handleMouseDown}
onMouseEnter={this.handleMouseEnter}
onMouseMove={this.handleMouseMove}
title={option.label}>
{option.short ? option.short : this.props.children}
- {option.complement &&
- <div className="pull-right text-muted-2">
- {option.complement}
- </div>}
</div>
);
}
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 446bf98b57a..14d16176c63 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
@@ -35,6 +35,7 @@ it('should render option bar open', () => {
visualization="risk"
projects={[1, 2, 3]}
projectsAppState={{ total: 3 }}
+ user={{ isLoggedIn: true }}
/>
)
).toMatchSnapshot();
@@ -52,3 +53,26 @@ it('should call close method correctly', () => {
click(wrapper.find('.projects-topbar-button'));
expect(toggle.mock.calls).toMatchSnapshot();
});
+
+it('should render switch the default sorting option for anonymous users', () => {
+ expect(
+ shallow(
+ <ProjectsOptionBar
+ open={true}
+ view="overall"
+ visualization="risk"
+ user={{ isLoggedIn: true }}
+ />
+ ).find('ProjectsSortingSelect')
+ ).toMatchSnapshot();
+ expect(
+ shallow(
+ <ProjectsOptionBar
+ open={true}
+ view="leak"
+ visualization="risk"
+ user={{ isLoggedIn: false }}
+ />
+ ).find('ProjectsSortingSelect')
+ ).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelect-test.js b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelect-test.js
index 472558d0085..4906bf180b2 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelect-test.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectsSortingSelect-test.js
@@ -22,17 +22,27 @@ import { shallow } from 'enzyme';
import ProjectsSortingSelect from '../ProjectsSortingSelect';
it('should render correctly for overall view', () => {
- expect(shallow(<ProjectsSortingSelect selectedSort="name" view="overall" />)).toMatchSnapshot();
+ expect(
+ shallow(<ProjectsSortingSelect selectedSort="name" view="overall" defaultOption="name" />)
+ ).toMatchSnapshot();
});
it('should render correctly for leak view', () => {
expect(
- shallow(<ProjectsSortingSelect selectedSort="new_coverage" view="leak" />)
+ shallow(
+ <ProjectsSortingSelect
+ selectedSort="new_coverage"
+ view="leak"
+ defaultOption="analysis_date"
+ />
+ )
).toMatchSnapshot();
});
it('should handle the descending sort direction', () => {
expect(
- shallow(<ProjectsSortingSelect selectedSort="-vulnerability" view="overall" />)
+ shallow(
+ <ProjectsSortingSelect selectedSort="-vulnerability" view="overall" defaultOption="name" />
+ )
).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 12099c9db00..15051129d68 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
@@ -39,6 +39,7 @@ exports[`should render disabled sorting options for visualizations 1`] = `
<div>
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select disabled"
+ defaultOption="analysis_date"
view="visualizations"
/>
</div>
@@ -74,6 +75,7 @@ exports[`should render option bar closed 1`] = `
/>
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select"
+ defaultOption="analysis_date"
view="overall"
/>
</div>
@@ -108,6 +110,7 @@ exports[`should render option bar open 1`] = `
/>
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select"
+ defaultOption="name"
view="leak"
/>
</div>
@@ -115,3 +118,19 @@ exports[`should render option bar open 1`] = `
</div>
</div>
`;
+
+exports[`should render switch the default sorting option for anonymous users 1`] = `
+<ProjectsSortingSelect
+ className="projects-topbar-item js-projects-sorting-select"
+ defaultOption="name"
+ view="overall"
+/>
+`;
+
+exports[`should render switch the default sorting option for anonymous users 2`] = `
+<ProjectsSortingSelect
+ className="projects-topbar-item js-projects-sorting-select"
+ defaultOption="analysis_date"
+ view="leak"
+/>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelect-test.js.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelect-test.js.snap
index c5ef95acbd7..7a004599bfb 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelect-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectsSortingSelect-test.js.snap
@@ -40,51 +40,43 @@ exports[`should handle the descending sort direction 1`] = `
options={
Array [
Object {
- "complement": undefined,
- "label": "projects.sorting.name",
- "short": undefined,
+ "class": undefined,
+ "label": "projects.sorting.name (projects.sorting.default)",
"value": "name",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.analysis_date",
- "short": undefined,
"value": "analysis_date",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.reliability",
- "short": undefined,
"value": "reliability",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.security",
- "short": undefined,
"value": "security",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.maintainability",
- "short": undefined,
"value": "maintainability",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.coverage",
- "short": undefined,
"value": "coverage",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.duplications",
- "short": undefined,
"value": "duplications",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.size",
- "short": undefined,
"value": "size",
},
]
@@ -157,51 +149,43 @@ exports[`should render correctly for leak view 1`] = `
options={
Array [
Object {
- "complement": undefined,
- "label": "projects.sorting.name",
- "short": undefined,
- "value": "name",
+ "class": undefined,
+ "label": "projects.sorting.analysis_date (projects.sorting.default)",
+ "value": "analysis_date",
},
Object {
- "complement": undefined,
- "label": "projects.sorting.analysis_date",
- "short": undefined,
- "value": "analysis_date",
+ "class": undefined,
+ "label": "projects.sorting.name",
+ "value": "name",
},
Object {
- "complement": "projects.sorting.on_new_code",
+ "class": "projects-leak-sorting-option",
"label": "projects.sorting.new_reliability",
- "short": "projects.sorting.new_reliability.short",
"value": "new_reliability",
},
Object {
- "complement": "projects.sorting.on_new_code",
+ "class": "projects-leak-sorting-option",
"label": "projects.sorting.new_security",
- "short": "projects.sorting.new_security.short",
"value": "new_security",
},
Object {
- "complement": "projects.sorting.on_new_code",
+ "class": "projects-leak-sorting-option",
"label": "projects.sorting.new_maintainability",
- "short": "projects.sorting.new_maintainability.short",
"value": "new_maintainability",
},
Object {
- "complement": "projects.sorting.on_new_code",
+ "class": "projects-leak-sorting-option",
"label": "projects.sorting.new_coverage",
- "short": "projects.sorting.new_coverage.short",
"value": "new_coverage",
},
Object {
- "complement": "projects.sorting.on_new_lines",
+ "class": "projects-leak-sorting-option",
"label": "projects.sorting.new_duplications",
- "short": "projects.sorting.new_duplications.short",
"value": "new_duplications",
},
Object {
- "complement": undefined,
+ "class": "projects-leak-sorting-option",
"label": "projects.sorting.new_lines",
- "short": undefined,
"value": "new_lines",
},
]
@@ -274,51 +258,43 @@ exports[`should render correctly for overall view 1`] = `
options={
Array [
Object {
- "complement": undefined,
- "label": "projects.sorting.name",
- "short": undefined,
+ "class": undefined,
+ "label": "projects.sorting.name (projects.sorting.default)",
"value": "name",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.analysis_date",
- "short": undefined,
"value": "analysis_date",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.reliability",
- "short": undefined,
"value": "reliability",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.security",
- "short": undefined,
"value": "security",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.maintainability",
- "short": undefined,
"value": "maintainability",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.coverage",
- "short": undefined,
"value": "coverage",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.duplications",
- "short": undefined,
"value": "duplications",
},
Object {
- "complement": undefined,
+ "class": undefined,
"label": "projects.sorting.size",
- "short": undefined,
"value": "size",
},
]
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 aeffc580da6..f9b1b627502 100644
--- a/server/sonar-web/src/main/js/apps/projects/styles.css
+++ b/server/sonar-web/src/main/js/apps/projects/styles.css
@@ -112,6 +112,14 @@
border: 1px solid #eae3c7;
}
+.projects-leak-sorting-option {
+ background-color: #fbf3d5;
+ margin-bottom: 2px;
+}
+
+.projects-leak-sorting-option.is-focused {
+ background-color: #eae3c7;
+}
.project-card-measures .project-card-measure {
width: 120px;
diff --git a/server/sonar-web/src/main/js/apps/projects/utils.js b/server/sonar-web/src/main/js/apps/projects/utils.js
index 85d898e64a0..008bdf5cb6a 100644
--- a/server/sonar-web/src/main/js/apps/projects/utils.js
+++ b/server/sonar-web/src/main/js/apps/projects/utils.js
@@ -61,12 +61,12 @@ export const SORTING_METRICS = [
export const SORTING_LEAK_METRICS = [
{ value: 'name' },
{ value: 'analysis_date' },
- { value: 'new_reliability', complement: 'on_new_code' },
- { value: 'new_security', complement: 'on_new_code' },
- { value: 'new_maintainability', complement: 'on_new_code' },
- { value: 'new_coverage', complement: 'on_new_code' },
- { value: 'new_duplications', complement: 'on_new_lines' },
- { value: 'new_lines' }
+ { value: 'new_reliability', class: 'projects-leak-sorting-option' },
+ { value: 'new_security', class: 'projects-leak-sorting-option' },
+ { value: 'new_maintainability', class: 'projects-leak-sorting-option' },
+ { value: 'new_coverage', class: 'projects-leak-sorting-option' },
+ { value: 'new_duplications', class: 'projects-leak-sorting-option' },
+ { value: 'new_lines', class: 'projects-leak-sorting-option' }
];
export const SORTING_SWITCH = {