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 = {
onToggleOptionBar={this.props.optionBarToggle}
open={optionBarOpen}
selectedSort={selectedSort}
+ user={this.props.user}
view={view}
visualization={visualization}
/>
projects: Array<*>,
projectsAppState: { loading: boolean, total?: number },
selectedSort: string,
+ user?: { isLoggedIn: boolean },
view: string,
visualization?: string
};
};
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}
return (
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select"
+ defaultOption={defaultOption}
onChange={this.props.onSortChange}
selectedSort={this.props.selectedSort}
view={this.props.view}
*/
// @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';
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 = {
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
}));
};
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}
/>
*/
//@flow
import React from 'react';
+import classNames from 'classnames';
import type { Option } from './ProjectsSortingSelect';
type Props = {
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>
);
}
visualization="risk"
projects={[1, 2, 3]}
projectsAppState={{ total: 3 }}
+ user={{ isLoggedIn: true }}
/>
)
).toMatchSnapshot();
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();
+});
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();
});
<div>
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select disabled"
+ defaultOption="analysis_date"
view="visualizations"
/>
</div>
/>
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select"
+ defaultOption="analysis_date"
view="overall"
/>
</div>
/>
<ProjectsSortingSelect
className="projects-topbar-item js-projects-sorting-select"
+ defaultOption="name"
view="leak"
/>
</div>
</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"
+/>
+`;
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",
},
]
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",
},
]
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",
},
]
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;
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 = {
projects.sort_by=Sort by
projects.sort_ascending=Result sorted in ascending order
projects.sort_descending=Result sorted in descending order
-projects.sorting.name=Name (default)
+projects.sorting.default=default
+projects.sorting.name=Name
projects.sorting.analysis_date=Last analysis date
projects.sorting.reliability=Reliability
projects.sorting.security=Security
projects.sorting.coverage=Coverage
projects.sorting.duplications=Duplications
projects.sorting.size=Size
-projects.sorting.new_reliability=Reliability on New Code
-projects.sorting.new_security=Security on New Code
-projects.sorting.new_maintainability=Maintainability on New Code
-projects.sorting.new_coverage=Coverage on New Code
-projects.sorting.new_duplications=Duplications on New Lines
-projects.sorting.new_reliability.short=Reliability
-projects.sorting.new_security.short=Security
-projects.sorting.new_maintainability.short=Maintainability
-projects.sorting.new_coverage.short=Coverage
-projects.sorting.new_duplications.short=Duplications
+projects.sorting.new_reliability=Reliability
+projects.sorting.new_security=Security
+projects.sorting.new_maintainability=Maintainability
+projects.sorting.new_coverage=Coverage
+projects.sorting.new_duplications=Duplications
projects.sorting.new_lines=New Lines
projects.sorting.on_new_code=on New Code
projects.sorting.on_new_lines=on New Lines