<div className="layout-page-side-inner">
<div className="layout-page-filters">
<PageSidebar
- query={query}
isFavorite={this.props.isFavorite}
organization={this.props.organization}
+ query={query}
+ view={view}
+ visualization={visualization}
/>
</div>
</div>
import { translate } from '../../../helpers/l10n';
import { saveAll, saveFavorite } from '../utils';
+type Props = {
+ user: {
+ isLoggedIn?: boolean
+ },
+ organization?: { key: string },
+ query: { [string]: string }
+};
+
export default class FavoriteFilter extends React.PureComponent {
+ props: Props;
+
handleSaveFavorite = () => {
if (!this.props.organization) {
saveFavorite();
<div className="button-group">
<Link
id="favorite-projects"
- to={pathnameForFavorite}
+ to={{ pathname: pathnameForFavorite, query: this.props.query }}
className="button"
activeClassName="button-active"
onClick={this.handleSaveFavorite}>
</Link>
<IndexLink
id="all-projects"
- to={pathnameForAll}
+ to={{ pathname: pathnameForAll, query: this.props.query }}
className="button"
activeClassName="button-active"
onClick={this.handleSaveAll}>
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+//@flow
import React from 'react';
import { Link } from 'react-router';
import FavoriteFilterContainer from './FavoriteFilterContainer';
-import CoverageFilter from '../filters/CoverageFilter';
-import DuplicationsFilter from '../filters/DuplicationsFilter';
-import SizeFilter from '../filters/SizeFilter';
+import LanguagesFilterContainer from '../filters/LanguagesFilterContainer';
+import PageSidebarOverall from './PageSidebarOverall';
import QualityGateFilter from '../filters/QualityGateFilter';
-import ReliabilityFilter from '../filters/ReliabilityFilter';
-import SecurityFilter from '../filters/SecurityFilter';
-import MaintainabilityFilter from '../filters/MaintainabilityFilter';
-import TagsFilterContainer from '../filters/TagsFilterContainer';
import SearchFilterContainer from '../filters/SearchFilterContainer';
-import LanguagesFilterContainer from '../filters/LanguagesFilterContainer';
+import TagsFilterContainer from '../filters/TagsFilterContainer';
import { translate } from '../../../helpers/l10n';
-export default class PageSidebar extends React.PureComponent {
- static propTypes = {
- query: React.PropTypes.object.isRequired,
- isFavorite: React.PropTypes.bool.isRequired,
- organization: React.PropTypes.object
- };
+type Props = {
+ isFavorite: boolean,
+ organization?: { key: string },
+ query: { [string]: string },
+ view: string,
+ visualization: string
+};
- render() {
- const { query } = this.props;
+export default function PageSidebar({
+ query,
+ isFavorite,
+ organization,
+ view,
+ visualization
+}: Props) {
+ const isFiltered = Object.keys(query)
+ .filter(key => key !== 'view' && key !== 'visualization')
+ .some(key => query[key] != null);
+ const isLeakView = view === 'leak';
+ const basePathName = organization ? `/organizations/${organization.key}/projects` : '/projects';
+ const pathname = basePathName + (isFavorite ? '/favorite' : '');
- const isFiltered = Object.keys(query)
- .filter(key => key !== 'view' && key !== 'visualization')
- .some(key => query[key] != null);
+ let linkQuery: ?{ view: string, visualization?: string };
+ if (view !== 'overall') {
+ linkQuery = { view };
- const basePathName = this.props.organization
- ? `/organizations/${this.props.organization.key}/projects`
- : '/projects';
- const pathname = basePathName + (this.props.isFavorite ? '/favorite' : '');
- const linkQuery = query.view === 'visualizations'
- ? { view: query.view, visualization: query.visualization }
- : undefined;
-
- return (
- <div>
- <FavoriteFilterContainer organization={this.props.organization} />
+ if (view === 'visualizations') {
+ linkQuery.visualization = visualization;
+ }
+ }
- <div className="projects-facets-header clearfix">
- {isFiltered &&
- <div className="projects-facets-reset">
- <Link to={{ pathname, query: linkQuery }} className="button button-red">
- {translate('clear_all_filters')}
- </Link>
- </div>}
+ return (
+ <div>
+ <FavoriteFilterContainer query={linkQuery} organization={organization} />
- <h3>{translate('filters')}</h3>
- <SearchFilterContainer
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- </div>
+ <div className="projects-facets-header clearfix">
+ {isFiltered &&
+ <div className="projects-facets-reset">
+ <Link to={{ pathname, query: linkQuery }} className="button button-red">
+ {translate('clear_all_filters')}
+ </Link>
+ </div>}
- <QualityGateFilter
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- <ReliabilityFilter
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- <SecurityFilter
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- <MaintainabilityFilter
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- <CoverageFilter
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- <DuplicationsFilter
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- <SizeFilter
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- <LanguagesFilterContainer
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
- <TagsFilterContainer
- query={query}
- isFavorite={this.props.isFavorite}
- organization={this.props.organization}
- />
+ <h3>{translate('filters')}</h3>
+ <SearchFilterContainer query={query} isFavorite={isFavorite} organization={organization} />
</div>
- );
- }
+ <QualityGateFilter query={query} isFavorite={isFavorite} organization={organization} />
+ {!isLeakView &&
+ <PageSidebarOverall query={query} isFavorite={isFavorite} organization={organization} />}
+ <LanguagesFilterContainer query={query} isFavorite={isFavorite} organization={organization} />
+ <TagsFilterContainer query={query} isFavorite={isFavorite} organization={organization} />
+ </div>
+ );
}
--- /dev/null
+/*
+ * 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.
+ */
+//@flow
+import React from 'react';
+import CoverageFilter from '../filters/CoverageFilter';
+import DuplicationsFilter from '../filters/DuplicationsFilter';
+import SizeFilter from '../filters/SizeFilter';
+import ReliabilityFilter from '../filters/ReliabilityFilter';
+import SecurityFilter from '../filters/SecurityFilter';
+import MaintainabilityFilter from '../filters/MaintainabilityFilter';
+
+type Props = {
+ isFavorite: boolean,
+ organization?: { key: string },
+ query: { [string]: string }
+};
+
+export default function PageSidebarOverall({ query, isFavorite, organization }: Props) {
+ return (
+ <div>
+ <ReliabilityFilter query={query} isFavorite={isFavorite} organization={organization} />
+ <SecurityFilter query={query} isFavorite={isFavorite} organization={organization} />
+ <MaintainabilityFilter query={query} isFavorite={isFavorite} organization={organization} />
+ <CoverageFilter query={query} isFavorite={isFavorite} organization={organization} />
+ <DuplicationsFilter query={query} isFavorite={isFavorite} organization={organization} />
+ <SizeFilter query={query} isFavorite={isFavorite} organization={organization} />
+ </div>
+ );
+}
import { shallow } from 'enzyme';
import PageSidebar from '../PageSidebar';
-it('should handle `view` and `visualization`', () => {
- const query = {
- view: 'visualizations',
- visualization: 'bugs'
- };
- const sidebar = shallow(<PageSidebar query={query} isFavorite={false} />);
+it('should render correctly', () => {
+ const sidebar = shallow(
+ <PageSidebar query={{ size: '3' }} view="overall" visualization="risk" isFavorite={true} />
+ );
+ expect(sidebar).toMatchSnapshot();
+});
+
+it('should render `leak` view correctly', () => {
+ const sidebar = shallow(
+ <PageSidebar query={{ view: 'leak' }} view="leak" visualization="risk" isFavorite={false} />
+ );
+ expect(sidebar).toMatchSnapshot();
+});
+
+it('reset function should work correctly with view and visualizations', () => {
+ const sidebar = shallow(
+ <PageSidebar
+ query={{ view: 'visualizations', visualization: 'bugs' }}
+ view="visualizations"
+ visualization="bugs"
+ isFavorite={false}
+ />
+ );
expect(sidebar.find('.projects-facets-reset')).toMatchSnapshot();
- sidebar.setProps({ query: { ...query, size: '3' } });
+ sidebar.setProps({ query: { size: '3' } });
expect(sidebar.find('.projects-facets-reset')).toMatchSnapshot();
});
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should handle \`view\` and \`visualization\` 1`] = `undefined`;
+exports[`reset function should work correctly with view and visualizations 1`] = `undefined`;
-exports[`should handle \`view\` and \`visualization\` 2`] = `
+exports[`reset function should work correctly with view and visualizations 2`] = `
<div
className="projects-facets-reset"
>
</Link>
</div>
`;
+
+exports[`should render \`leak\` view correctly 1`] = `
+<div>
+ <Connect(FavoriteFilter)
+ query={
+ Object {
+ "view": "leak",
+ }
+ }
+ />
+ <div
+ className="projects-facets-header clearfix"
+ >
+ <h3>
+ filters
+ </h3>
+ <withRouter(SearchFilterContainer)
+ isFavorite={false}
+ query={
+ Object {
+ "view": "leak",
+ }
+ }
+ />
+ </div>
+ <QualityGateFilter
+ isFavorite={false}
+ query={
+ Object {
+ "view": "leak",
+ }
+ }
+ />
+ <Connect(withRouter(LanguagesFilter))
+ isFavorite={false}
+ query={
+ Object {
+ "view": "leak",
+ }
+ }
+ />
+ <Connect(withRouter(TagsFilter))
+ isFavorite={false}
+ query={
+ Object {
+ "view": "leak",
+ }
+ }
+ />
+</div>
+`;
+
+exports[`should render correctly 1`] = `
+<div>
+ <Connect(FavoriteFilter) />
+ <div
+ className="projects-facets-header clearfix"
+ >
+ <div
+ className="projects-facets-reset"
+ >
+ <Link
+ className="button button-red"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/projects/favorite",
+ "query": undefined,
+ }
+ }
+ >
+ clear_all_filters
+ </Link>
+ </div>
+ <h3>
+ filters
+ </h3>
+ <withRouter(SearchFilterContainer)
+ isFavorite={true}
+ query={
+ Object {
+ "size": "3",
+ }
+ }
+ />
+ </div>
+ <QualityGateFilter
+ isFavorite={true}
+ query={
+ Object {
+ "size": "3",
+ }
+ }
+ />
+ <PageSidebarOverall
+ isFavorite={true}
+ query={
+ Object {
+ "size": "3",
+ }
+ }
+ />
+ <Connect(withRouter(LanguagesFilter))
+ isFavorite={true}
+ query={
+ Object {
+ "size": "3",
+ }
+ }
+ />
+ <Connect(withRouter(TagsFilter))
+ isFavorite={true}
+ query={
+ Object {
+ "size": "3",
+ }
+ }
+ />
+</div>
+`;