aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/projects
diff options
context:
space:
mode:
authorJeremy Davis <jeremy.davis@sonarsource.com>2020-04-01 16:40:30 +0200
committersonartech <sonartech@sonarsource.com>2020-04-15 20:03:38 +0000
commitafa5ca444414f8c4352afb53528b9514d1c22c77 (patch)
tree24e34f6255bb9dc131443c7749f230fb61eaa38d /server/sonar-web/src/main/js/apps/projects
parentf535e9b3fc11d6020a0d6143ab3931d2d5566627 (diff)
downloadsonarqube-afa5ca444414f8c4352afb53528b9514d1c22c77.tar.gz
sonarqube-afa5ca444414f8c4352afb53528b9514d1c22c77.zip
SONAR-13189 Add qualifier facet to projects
Diffstat (limited to 'server/sonar-web/src/main/js/apps/projects')
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx88
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx38
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx28
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx78
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap209
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap162
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx67
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualifierFilter-test.tsx38
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap13
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap33
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap26
-rw-r--r--server/sonar-web/src/main/js/apps/projects/query.ts12
-rw-r--r--server/sonar-web/src/main/js/apps/projects/utils.ts9
61 files changed, 381 insertions, 518 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
index 07aee81409d..89e22be3c20 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx
@@ -28,13 +28,11 @@ import { addSideBarClass, removeSideBarClass } from 'sonar-ui-common/helpers/pag
import { get, save } from 'sonar-ui-common/helpers/storage';
import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget';
import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
-import { OnboardingContext } from '../../../app/components/OnboardingContext';
import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
import '../../../components/search-navigator.css';
-import { isSonarCloud } from '../../../helpers/system';
import { isLoggedIn } from '../../../helpers/users';
-import OrganizationEmpty from '../../organizations/components/OrganizationEmpty';
+import { ComponentQualifier } from '../../../types/component';
import { hasFilterParams, hasVisualizationParams, parseUrlQuery, Query } from '../query';
import '../styles.css';
import { Facets, Project } from '../types';
@@ -49,13 +47,13 @@ interface Props {
isFavorite: boolean;
location: Pick<Location, 'pathname' | 'query'>;
organization: T.Organization | undefined;
+ qualifiers: ComponentQualifier[];
router: Pick<Router, 'push' | 'replace'>;
storageOptionsSuffix?: string;
}
interface State {
facets?: Facets;
- initialLoading: boolean;
loading: boolean;
pageIndex?: number;
projects?: Project[];
@@ -72,7 +70,7 @@ export class AllProjects extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
- this.state = { initialLoading: true, loading: true, query: {} };
+ this.state = { loading: true, query: {} };
}
componentDidMount() {
@@ -83,23 +81,13 @@ export class AllProjects extends React.PureComponent<Props, State> {
return;
}
this.handleQueryChange(true);
- this.updateFooterClass();
+ addSideBarClass();
}
componentDidUpdate(prevProps: Props) {
if (prevProps.location.query !== this.props.location.query) {
this.handleQueryChange(false);
}
-
- if (
- prevProps.organization &&
- this.props.organization &&
- prevProps.organization.key !== this.props.organization.key
- ) {
- this.setState({ initialLoading: true });
- }
-
- this.updateFooterClass();
}
componentWillUnmount() {
@@ -113,7 +101,6 @@ export class AllProjects extends React.PureComponent<Props, State> {
if (this.mounted) {
this.setState({
facets: response.facets,
- initialLoading: false,
loading: false,
pageIndex: 1,
projects: response.projects,
@@ -232,7 +219,7 @@ export class AllProjects extends React.PureComponent<Props, State> {
stopLoading = () => {
if (this.mounted) {
- this.setState({ initialLoading: false, loading: false });
+ this.setState({ loading: false });
}
};
@@ -241,19 +228,6 @@ export class AllProjects extends React.PureComponent<Props, State> {
this.props.router.push({ pathname: this.props.location.pathname, query });
};
- updateFooterClass = () => {
- const { organization } = this.props;
- const { initialLoading, projects } = this.state;
- const isOrganizationContext = isSonarCloud() && organization;
- const isEmpty = projects && projects.length === 0;
-
- if (isOrganizationContext && (initialLoading || isEmpty)) {
- removeSideBarClass();
- } else {
- addSideBarClass();
- }
- };
-
renderSide = () => (
<ScreenPositionHelper className="layout-page-side-outer">
{({ top }) => (
@@ -267,12 +241,12 @@ export class AllProjects extends React.PureComponent<Props, State> {
/>
<PageSidebar
+ applicationsEnabled={this.props.qualifiers.includes(ComponentQualifier.Application)}
facets={this.state.facets}
onClearAll={this.handleClearAll}
onQueryChange={this.updateLocationQuery}
organization={this.props.organization}
query={this.state.query}
- showFavoriteFilter={!isSonarCloud()}
view={this.getView()}
visualization={this.getVisualization()}
/>
@@ -316,7 +290,7 @@ export class AllProjects extends React.PureComponent<Props, State> {
<div className="layout-page-main-inner">
{this.state.projects && (
<Visualizations
- displayOrganizations={!this.props.organization && isSonarCloud()}
+ displayOrganizations={false}
projects={this.state.projects}
sort={this.state.query.sort}
total={this.state.total}
@@ -350,51 +324,19 @@ export class AllProjects extends React.PureComponent<Props, State> {
};
render() {
- const { organization } = this.props;
- const { projects } = this.state;
- const isOrganizationContext = isSonarCloud() && organization;
- const initialLoading = isOrganizationContext && this.state.initialLoading;
- const organizationEmpty =
- isOrganizationContext &&
- projects &&
- projects.length === 0 &&
- !this.state.loading &&
- !hasFilterParams(this.state.query);
-
return (
<div className="layout-page projects-page" id="projects-page">
<Suggestions suggestions="projects" />
<Helmet defer={false} title={translate('projects.page')} />
- {initialLoading ? (
- <div className="display-flex-space-around width-100 huge-spacer-top">
- <DeferredSpinner />
- </div>
- ) : (
- <>
- {!organizationEmpty && this.renderSide()}
-
- <div className="layout-page-main">
- <A11ySkipTarget anchor="projects_main" />
-
- {organizationEmpty && organization ? (
- <OnboardingContext.Consumer>
- {openProjectOnboarding => (
- <OrganizationEmpty
- openProjectOnboarding={openProjectOnboarding}
- organization={organization}
- />
- )}
- </OnboardingContext.Consumer>
- ) : (
- <>
- {this.renderHeader()}
- {this.renderMain()}
- </>
- )}
- </div>
- </>
- )}
+ {this.renderSide()}
+
+ <div className="layout-page-main">
+ <A11ySkipTarget anchor="projects_main" />
+
+ {this.renderHeader()}
+ {this.renderMain()}
+ </div>
</div>
);
}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx
index 09c3f522345..640630d61ed 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx
@@ -19,11 +19,12 @@
*/
import { connect } from 'react-redux';
import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent';
-import { areThereCustomOrganizations, getCurrentUser, Store } from '../../../store/rootReducer';
+import { getAppState, getCurrentUser, Store } from '../../../store/rootReducer';
+import { ComponentQualifier } from '../../../types/component';
const stateToProps = (state: Store) => ({
currentUser: getCurrentUser(state),
- organizationsEnabled: areThereCustomOrganizations(state)
+ qualifiers: getAppState(state).qualifiers as ComponentQualifier[]
});
export default connect(stateToProps)(lazyLoadComponent(() => import('./AllProjects')));
diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx
index 722640090be..b92e20b1e66 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx
@@ -30,6 +30,7 @@ import NewLinesFilter from '../filters/NewLinesFilter';
import NewMaintainabilityFilter from '../filters/NewMaintainabilityFilter';
import NewReliabilityFilter from '../filters/NewReliabilityFilter';
import NewSecurityFilter from '../filters/NewSecurityFilter';
+import QualifierFilter from '../filters/QualifierFilter';
import QualityGateFilter from '../filters/QualityGateFilter';
import ReliabilityFilter from '../filters/ReliabilityFilter';
import SecurityFilter from '../filters/SecurityFilter';
@@ -41,23 +42,31 @@ import { Facets } from '../types';
import ClearAll from './ClearAll';
import FavoriteFilterContainer from './FavoriteFilterContainer';
-interface Props {
+export interface PageSidebarProps {
+ applicationsEnabled: boolean;
facets?: Facets;
onClearAll: () => void;
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
query: T.RawQuery;
- showFavoriteFilter: boolean;
view: string;
visualization: string;
}
-export default function PageSidebar(props: Props) {
- const { facets, onQueryChange, query, organization, view, visualization } = props;
+export default function PageSidebar(props: PageSidebarProps) {
+ const {
+ applicationsEnabled,
+ facets,
+ onQueryChange,
+ query,
+ organization,
+ view,
+ visualization
+ } = props;
const isFiltered = hasFilterParams(query);
const isLeakView = view === 'leak';
const maxFacetValue = getMaxFacetValue(facets);
- const facetProps = { onQueryChange, maxFacetValue, organization, query };
+ const facetProps = { onQueryChange, maxFacetValue, organization };
let linkQuery: T.RawQuery | undefined = undefined;
if (view !== 'overall') {
@@ -70,9 +79,7 @@ export default function PageSidebar(props: Props) {
return (
<div>
- {props.showFavoriteFilter && (
- <FavoriteFilterContainer organization={organization} query={linkQuery} />
- )}
+ <FavoriteFilterContainer organization={organization} query={linkQuery} />
<div className="projects-facets-header clearfix">
{isFiltered && <ClearAll onClearAll={props.onClearAll} />}
@@ -161,9 +168,22 @@ export default function PageSidebar(props: Props) {
<LanguagesFilterContainer
{...facetProps}
facet={getFacet(facets, 'languages')}
+ query={query}
value={query.languages}
/>
- <TagsFilter {...facetProps} facet={getFacet(facets, 'tags')} value={query.tags} />
+ {applicationsEnabled && (
+ <QualifierFilter
+ {...facetProps}
+ facet={getFacet(facets, 'qualifier')}
+ value={query.qualifier}
+ />
+ )}
+ <TagsFilter
+ {...facetProps}
+ facet={getFacet(facets, 'tags')}
+ query={query}
+ value={query.tags}
+ />
</div>
);
}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx
index 3add3f6bbcb..438e519eb61 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx
@@ -20,8 +20,6 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import { get, save } from 'sonar-ui-common/helpers/storage';
-import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { isSonarCloud } from '../../../../helpers/system';
import { ComponentQualifier } from '../../../../types/component';
import { AllProjects } from '../AllProjects';
@@ -57,14 +55,11 @@ jest.mock('sonar-ui-common/helpers/storage', () => ({
save: jest.fn()
}));
-jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn() }));
-
const fetchProjects = require('../../utils').fetchProjects as jest.Mock;
beforeEach(() => {
(get as jest.Mock).mockImplementation(() => null);
(save as jest.Mock).mockClear();
- (isSonarCloud as jest.Mock).mockReturnValue(false);
fetchProjects.mockClear();
});
@@ -166,28 +161,6 @@ it('changes perspective to risk visualization', () => {
expect(save).toHaveBeenCalledWith('sonarqube.projects.visualization', 'risk', undefined);
});
-it('renders correctly empty organization', async () => {
- (isSonarCloud as jest.Mock).mockReturnValue(true);
- const wrapper = shallow(
- <AllProjects
- currentUser={{ isLoggedIn: true }}
- isFavorite={false}
- location={{ pathname: '/projects', query: {} }}
- organization={{ key: 'foo', name: 'Foo' }}
- router={{ push: jest.fn(), replace: jest.fn() }}
- />
- );
- expect(wrapper).toMatchSnapshot();
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
- wrapper.setState({
- loading: false,
- projects: [{ key: 'foo', measures: {}, name: 'Foo' }],
- total: 0
- });
- expect(wrapper).toMatchSnapshot();
-});
-
it('handles favorite projects', () => {
const wrapper = shallowRender();
expect(wrapper.state('projects')).toMatchSnapshot();
@@ -207,6 +180,7 @@ function shallowRender(
isFavorite={false}
location={{ pathname: '/projects', query: {} }}
organization={undefined}
+ qualifiers={[ComponentQualifier.Project, ComponentQualifier.Application]}
router={{ push, replace }}
{...props}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
index 197b42b5ea9..fc9969d2363 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
@@ -19,48 +19,70 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import PageSidebar from '../PageSidebar';
+import PageSidebar, { PageSidebarProps } from '../PageSidebar';
it('should render correctly', () => {
- const sidebar = shallow(
- <PageSidebar
- onClearAll={jest.fn()}
- onQueryChange={jest.fn()}
- query={{ size: '3' }}
- showFavoriteFilter={true}
- view="overall"
- visualization="risk"
- />
- );
+ const sidebar = shallowRender({
+ query: { size: '3' },
+ view: 'overall',
+ visualization: 'risk'
+ });
+
+ expect(sidebar).toMatchSnapshot();
+});
+
+it('should render correctly with no applications', () => {
+ const sidebar = shallowRender({
+ applicationsEnabled: false,
+ query: { size: '3' },
+ view: 'overall',
+ visualization: 'risk'
+ });
+
expect(sidebar).toMatchSnapshot();
});
it('should render `leak` view correctly', () => {
- const sidebar = shallow(
- <PageSidebar
- onClearAll={jest.fn()}
- onQueryChange={jest.fn()}
- query={{ view: 'leak' }}
- showFavoriteFilter={true}
- view="leak"
- visualization="risk"
- />
- );
+ const sidebar = shallowRender({
+ query: { view: 'leak' },
+ view: 'leak',
+ visualization: 'risk'
+ });
+ expect(sidebar).toMatchSnapshot();
+});
+
+it('should render `leak` view correctly with no applications', () => {
+ const sidebar = shallowRender({
+ applicationsEnabled: false,
+ query: { view: 'leak' },
+ view: 'leak',
+ visualization: 'risk'
+ });
expect(sidebar).toMatchSnapshot();
});
it('reset function should work correctly with view and visualizations', () => {
- const sidebar = shallow(
+ const sidebar = shallowRender({
+ query: { view: 'visualizations', visualization: 'bugs' },
+ view: 'visualizations',
+ visualization: 'bugs'
+ });
+
+ expect(sidebar.find('ClearAll').exists()).toBe(false);
+ sidebar.setProps({ query: { size: '3' } });
+ expect(sidebar.find('ClearAll').exists()).toBe(true);
+});
+
+function shallowRender(overrides: Partial<PageSidebarProps> = {}) {
+ return shallow(
<PageSidebar
+ applicationsEnabled={true}
onClearAll={jest.fn()}
onQueryChange={jest.fn()}
query={{ view: 'visualizations', visualization: 'bugs' }}
- showFavoriteFilter={true}
- view="visualizations"
+ view="overall"
visualization="bugs"
+ {...overrides}
/>
);
- expect(sidebar.find('ClearAll').exists()).toBe(false);
- sidebar.setProps({ query: { size: '3' } });
- expect(sidebar.find('ClearAll').exists()).toBe(true);
-});
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap
index 58f1e3f2750..dd7306ad88d 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap
@@ -97,6 +97,7 @@ exports[`renders 1`] = `
"new_reliability": undefined,
"new_security": undefined,
"new_security_review_rating": undefined,
+ "qualifier": undefined,
"reliability": undefined,
"search": undefined,
"security": undefined,
@@ -155,6 +156,7 @@ exports[`renders 1`] = `
"new_reliability": undefined,
"new_security": undefined,
"new_security_review_rating": undefined,
+ "qualifier": undefined,
"reliability": undefined,
"search": undefined,
"security": undefined,
@@ -272,210 +274,3 @@ exports[`renders 2`] = `
</div>
</div>
`;
-
-exports[`renders correctly empty organization 1`] = `
-<div
- className="layout-page projects-page"
- id="projects-page"
->
- <Suggestions
- suggestions="projects"
- />
- <Helmet
- defer={false}
- encodeSpecialCharacters={true}
- title="projects.page"
- />
- <div
- className="display-flex-space-around width-100 huge-spacer-top"
- >
- <DeferredSpinner
- timeout={100}
- />
- </div>
-</div>
-`;
-
-exports[`renders correctly empty organization 2`] = `
-<div
- className="layout-page projects-page"
- id="projects-page"
->
- <Suggestions
- suggestions="projects"
- />
- <Helmet
- defer={false}
- encodeSpecialCharacters={true}
- title="projects.page"
- />
- <div
- className="layout-page-main"
- >
- <A11ySkipTarget
- anchor="projects_main"
- />
- <ContextConsumer>
- <Component />
- </ContextConsumer>
- </div>
-</div>
-`;
-
-exports[`renders correctly empty organization 3`] = `
-<div
- className="layout-page projects-page"
- id="projects-page"
->
- <Suggestions
- suggestions="projects"
- />
- <Helmet
- defer={false}
- encodeSpecialCharacters={true}
- title="projects.page"
- />
- <ScreenPositionHelper
- className="layout-page-side-outer"
- >
- <Component />
- </ScreenPositionHelper>
- <div
- className="layout-page-main"
- >
- <A11ySkipTarget
- anchor="projects_main"
- />
- <div
- className="layout-page-header-panel layout-page-main-header"
- >
- <div
- className="layout-page-header-panel-inner layout-page-main-header-inner"
- >
- <div
- className="layout-page-main-inner"
- >
- <PageHeader
- currentUser={
- Object {
- "isLoggedIn": true,
- }
- }
- isFavorite={false}
- loading={false}
- onPerspectiveChange={[Function]}
- onQueryChange={[Function]}
- onSortChange={[Function]}
- organization={
- Object {
- "key": "foo",
- "name": "Foo",
- }
- }
- projects={
- Array [
- Object {
- "key": "foo",
- "measures": Object {},
- "name": "Foo",
- },
- ]
- }
- query={
- Object {
- "coverage": undefined,
- "duplications": undefined,
- "gate": undefined,
- "languages": undefined,
- "maintainability": undefined,
- "new_coverage": undefined,
- "new_duplications": undefined,
- "new_lines": undefined,
- "new_maintainability": undefined,
- "new_reliability": undefined,
- "new_security": undefined,
- "new_security_review_rating": undefined,
- "reliability": undefined,
- "search": undefined,
- "security": undefined,
- "security_review_rating": undefined,
- "size": undefined,
- "sort": undefined,
- "tags": undefined,
- "view": undefined,
- "visualization": undefined,
- }
- }
- selectedSort="name"
- total={0}
- view="overall"
- visualization="risk"
- />
- </div>
- </div>
- </div>
- <div
- className="layout-page-main-inner"
- >
- <ProjectsList
- cardType="overall"
- currentUser={
- Object {
- "isLoggedIn": true,
- }
- }
- handleFavorite={[Function]}
- isFavorite={false}
- isFiltered={false}
- organization={
- Object {
- "key": "foo",
- "name": "Foo",
- }
- }
- projects={
- Array [
- Object {
- "key": "foo",
- "measures": Object {},
- "name": "Foo",
- },
- ]
- }
- query={
- Object {
- "coverage": undefined,
- "duplications": undefined,
- "gate": undefined,
- "languages": undefined,
- "maintainability": undefined,
- "new_coverage": undefined,
- "new_duplications": undefined,
- "new_lines": undefined,
- "new_maintainability": undefined,
- "new_reliability": undefined,
- "new_security": undefined,
- "new_security_review_rating": undefined,
- "reliability": undefined,
- "search": undefined,
- "security": undefined,
- "security_review_rating": undefined,
- "size": undefined,
- "sort": undefined,
- "tags": undefined,
- "view": undefined,
- "visualization": undefined,
- }
- }
- />
- <ListFooter
- count={1}
- loadMore={[Function]}
- loading={false}
- ready={true}
- total={0}
- />
- </div>
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap
index 8c607217185..ac6904b4bc7 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap
@@ -18,55 +18,42 @@ exports[`should render \`leak\` view correctly 1`] = `
</div>
<QualityGateFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "view": "leak",
- }
- }
/>
<NewReliabilityFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "view": "leak",
- }
- }
/>
<NewSecurityFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "view": "leak",
- }
- }
/>
<SecurityReviewFilter
className="leak-facet-box"
onQueryChange={[MockFunction]}
property="new_security_review_rating"
- query={
- Object {
- "view": "leak",
- }
- }
/>
<NewMaintainabilityFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "view": "leak",
- }
- }
/>
<NewCoverageFilter
onQueryChange={[MockFunction]}
+ />
+ <NewDuplicationsFilter
+ onQueryChange={[MockFunction]}
+ />
+ <NewLinesFilter
+ onQueryChange={[MockFunction]}
+ />
+ <Connect(LanguagesFilter)
+ onQueryChange={[MockFunction]}
query={
Object {
"view": "leak",
}
}
/>
- <NewDuplicationsFilter
+ <QualifierFilter
+ onQueryChange={[MockFunction]}
+ />
+ <TagsFilter
onQueryChange={[MockFunction]}
query={
Object {
@@ -74,14 +61,51 @@ exports[`should render \`leak\` view correctly 1`] = `
}
}
/>
- <NewLinesFilter
- onQueryChange={[MockFunction]}
+</div>
+`;
+
+exports[`should render \`leak\` view correctly with no applications 1`] = `
+<div>
+ <Connect(FavoriteFilter)
query={
Object {
"view": "leak",
}
}
/>
+ <div
+ className="projects-facets-header clearfix"
+ >
+ <h3>
+ filters
+ </h3>
+ </div>
+ <QualityGateFilter
+ onQueryChange={[MockFunction]}
+ />
+ <NewReliabilityFilter
+ onQueryChange={[MockFunction]}
+ />
+ <NewSecurityFilter
+ onQueryChange={[MockFunction]}
+ />
+ <SecurityReviewFilter
+ className="leak-facet-box"
+ onQueryChange={[MockFunction]}
+ property="new_security_review_rating"
+ />
+ <NewMaintainabilityFilter
+ onQueryChange={[MockFunction]}
+ />
+ <NewCoverageFilter
+ onQueryChange={[MockFunction]}
+ />
+ <NewDuplicationsFilter
+ onQueryChange={[MockFunction]}
+ />
+ <NewLinesFilter
+ onQueryChange={[MockFunction]}
+ />
<Connect(LanguagesFilter)
onQueryChange={[MockFunction]}
query={
@@ -116,67 +140,87 @@ exports[`should render correctly 1`] = `
</div>
<QualityGateFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "size": "3",
- }
- }
/>
<ReliabilityFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "size": "3",
- }
- }
/>
<SecurityFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "size": "3",
- }
- }
/>
<SecurityReviewFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "size": "3",
- }
- }
/>
<MaintainabilityFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "size": "3",
- }
- }
/>
<CoverageFilter
onQueryChange={[MockFunction]}
- query={
- Object {
- "size": "3",
- }
- }
/>
<DuplicationsFilter
onQueryChange={[MockFunction]}
+ />
+ <SizeFilter
+ onQueryChange={[MockFunction]}
+ value="3"
+ />
+ <Connect(LanguagesFilter)
+ onQueryChange={[MockFunction]}
query={
Object {
"size": "3",
}
}
/>
- <SizeFilter
+ <QualifierFilter
+ onQueryChange={[MockFunction]}
+ />
+ <TagsFilter
onQueryChange={[MockFunction]}
query={
Object {
"size": "3",
}
}
+ />
+</div>
+`;
+
+exports[`should render correctly with no applications 1`] = `
+<div>
+ <Connect(FavoriteFilter) />
+ <div
+ className="projects-facets-header clearfix"
+ >
+ <ClearAll
+ onClearAll={[MockFunction]}
+ />
+ <h3>
+ filters
+ </h3>
+ </div>
+ <QualityGateFilter
+ onQueryChange={[MockFunction]}
+ />
+ <ReliabilityFilter
+ onQueryChange={[MockFunction]}
+ />
+ <SecurityFilter
+ onQueryChange={[MockFunction]}
+ />
+ <SecurityReviewFilter
+ onQueryChange={[MockFunction]}
+ />
+ <MaintainabilityFilter
+ onQueryChange={[MockFunction]}
+ />
+ <CoverageFilter
+ onQueryChange={[MockFunction]}
+ />
+ <DuplicationsFilter
+ onQueryChange={[MockFunction]}
+ />
+ <SizeFilter
+ onQueryChange={[MockFunction]}
value="3"
/>
<Connect(LanguagesFilter)
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx
index b3e6b4ac240..4f720583ce7 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx
@@ -35,7 +35,6 @@ export interface Props {
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
property?: string;
- query: T.Dict<any>;
value?: any;
}
@@ -55,7 +54,6 @@ export default function CoverageFilter(props: Props) {
options={[1, 2, 3, 4, 5, 6]}
organization={props.organization}
property={property}
- query={props.query}
renderOption={renderOption}
value={props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx
index 7b9875cfb14..673a0d5df2a 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx
@@ -35,7 +35,6 @@ export interface Props {
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
property?: string;
- query: T.Dict<any>;
value?: any;
}
@@ -54,7 +53,6 @@ export default function DuplicationsFilter(props: Props) {
options={[1, 2, 3, 4, 5, 6]}
organization={props.organization}
property={property}
- query={props.query}
renderOption={renderOption}
value={props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx
index 0c331e76bdd..a76a69d6ceb 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx
@@ -30,7 +30,6 @@ interface Props {
className?: string;
onQueryChange: (change: T.RawQuery) => void;
options: Option[];
- query: T.Dict<any>;
renderOption: (option: Option, isSelected: boolean) => React.ReactNode;
value?: Option | Option[];
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx
index 324541f8441..9ff16d6a5a6 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx
@@ -33,7 +33,6 @@ interface Props {
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
property: string;
- query: T.Dict<any>;
value?: any;
}
@@ -53,7 +52,6 @@ export default function IssuesFilter(props: Props) {
options={[1, 2, 3, 4, 5]}
organization={props.organization}
property={props.property}
- query={props.query}
renderOption={renderOption}
value={props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx
index 2c75faaa03a..1a6c9a3ec3a 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx
@@ -79,7 +79,6 @@ export default class LanguagesFilter extends React.Component<Props> {
options={this.getSortedOptions(this.props.facet)}
organization={this.props.organization}
property={property}
- query={this.props.query}
renderOption={this.renderOption}
value={this.props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx
index a1798e6e98c..7d95f9cf26f 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx
@@ -30,7 +30,6 @@ interface Props {
maxFacetValue?: number;
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
- query: T.Dict<any>;
value?: any;
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx
index e760076cb0b..93bb00e69da 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx
@@ -31,7 +31,6 @@ export interface Props {
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
property?: string;
- query: T.Dict<any>;
value?: any;
}
@@ -50,7 +49,6 @@ export default function NewLinesFilter(props: Props) {
options={[1, 2, 3, 4, 5]}
organization={props.organization}
property={property}
- query={props.query}
renderOption={renderOption}
value={props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx
index cb326c2ff9f..ae1cf6cec6f 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx
@@ -29,7 +29,6 @@ interface Props {
maxFacetValue?: number;
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
- query: T.Dict<any>;
value?: any;
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx
index 4000d2837da..d17247295e8 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx
@@ -29,7 +29,6 @@ interface Props {
maxFacetValue?: number;
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
- query: T.Dict<any>;
value?: any;
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx
index 6c13f553e5e..1cc7f4a768e 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx
@@ -29,7 +29,6 @@ interface Props {
maxFacetValue?: number;
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
- query: T.Dict<any>;
value?: any;
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx
new file mode 100644
index 00000000000..4a8ada5c833
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx
@@ -0,0 +1,67 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { ComponentQualifier } from '../../../types/component';
+import { Facet } from '../types';
+import Filter from './Filter';
+import FilterHeader from './FilterHeader';
+
+export interface QualifierFilterProps {
+ facet?: Facet;
+ maxFacetValue?: number;
+ onQueryChange: (change: T.RawQuery) => void;
+ organization?: { key: string };
+ value: ComponentQualifier | undefined;
+}
+
+const options = [ComponentQualifier.Project, ComponentQualifier.Application];
+
+export default function QualifierFilter(props: QualifierFilterProps) {
+ const { facet, maxFacetValue, organization, value } = props;
+
+ return (
+ <Filter
+ facet={facet}
+ header={<FilterHeader name={translate('projects.facets.qualifier')} />}
+ maxFacetValue={maxFacetValue}
+ onQueryChange={props.onQueryChange}
+ options={options}
+ organization={organization}
+ property="qualifier"
+ renderOption={renderOption}
+ value={value}
+ />
+ );
+}
+
+function renderOption(option: string, selected: boolean) {
+ return (
+ <span className="display-flex-center">
+ <QualifierIcon
+ className="spacer-right"
+ fill={selected ? undefined : 'currentColor'}
+ qualifier={option}
+ />
+ {translate('qualifier', option)}
+ </span>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx
index 2bee422e1e9..c93b7714e96 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx
@@ -31,7 +31,6 @@ export interface Props {
maxFacetValue?: number;
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
- query: T.Dict<any>;
value?: any;
}
@@ -48,7 +47,6 @@ export default function QualityGateFilter(props: Props) {
options={options}
organization={props.organization}
property="gate"
- query={props.query}
renderOption={renderOption}
value={props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx
index fae5e9cc80f..c77839c16ba 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx
@@ -30,7 +30,6 @@ interface Props {
maxFacetValue?: number;
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
- query: T.Dict<any>;
value?: any;
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx
index 0e771cdf8cd..308af85f589 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx
@@ -30,7 +30,6 @@ interface Props {
maxFacetValue?: number;
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
- query: T.Dict<any>;
value?: any;
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx
index 971f5f7a08e..df7a9ad7b39 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx
@@ -32,7 +32,6 @@ export interface Props {
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
property?: string;
- query: T.Dict<any>;
value?: any;
}
@@ -53,14 +52,12 @@ export default function SecurityReviewFilter(props: Props) {
facet={props.facet}
header={
<FilterHeader name={translate('metric_domain.SecurityReview')}>
- {
- <span className="note little-spacer-left">
- {'( '}
- <SecurityHotspotIcon className="little-spacer-right" />
- {translate('metric.security_hotspots.name')}
- {' )'}
- </span>
- }
+ <span className="note little-spacer-left">
+ {'( '}
+ <SecurityHotspotIcon className="little-spacer-right" />
+ {translate('metric.security_hotspots.name')}
+ {' )'}
+ </span>
</FilterHeader>
}
highlightUnder={1}
@@ -69,7 +66,6 @@ export default function SecurityReviewFilter(props: Props) {
options={[1, 2, 3, 4, 5]}
organization={props.organization}
property={property}
- query={props.query}
renderOption={renderOption}
value={props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx
index 386ceb7b995..235e6a81904 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx
@@ -32,7 +32,6 @@ export interface Props {
onQueryChange: (change: T.RawQuery) => void;
organization?: { key: string };
property?: string;
- query: T.Dict<any>;
value?: any;
}
@@ -51,7 +50,6 @@ export default function SizeFilter(props: Props) {
options={[1, 2, 3, 4, 5]}
organization={props.organization}
property={property}
- query={props.query}
renderOption={renderOption}
value={props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx
index d31b017be9b..2fe20cbe45b 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx
@@ -121,7 +121,6 @@ export default class TagsFilter extends React.PureComponent<Props, State> {
options={this.getSortedOptions(this.props.facet)}
organization={this.props.organization}
property={property}
- query={this.props.query}
renderOption={this.renderOption}
value={this.props.value}
/>
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx
index e39cbd85d43..573c1e0d69f 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx
@@ -22,7 +22,7 @@ import * as React from 'react';
import CoverageFilter from '../CoverageFilter';
it('renders', () => {
- const wrapper = shallow(<CoverageFilter onQueryChange={jest.fn()} query={{}} />);
+ const wrapper = shallow(<CoverageFilter onQueryChange={jest.fn()} />);
expect(wrapper).toMatchSnapshot();
const renderOption = wrapper.prop('renderOption');
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx
index 5a72e02355a..c40816fd91a 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx
@@ -22,7 +22,7 @@ import * as React from 'react';
import DuplicationsFilter from '../DuplicationsFilter';
it('renders', () => {
- const wrapper = shallow(<DuplicationsFilter onQueryChange={jest.fn()} query={{}} />);
+ const wrapper = shallow(<DuplicationsFilter onQueryChange={jest.fn()} />);
expect(wrapper).toMatchSnapshot();
const renderOption = wrapper.prop('renderOption');
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx
index 2d25b9691be..d95f494f863 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx
@@ -60,15 +60,14 @@ it('renders facet bar chart', () => {
).toMatchSnapshot();
});
-function shallowRender(props?: any) {
- return shallow(
+function shallowRender(overrides: Partial<Filter['props']> = {}) {
+ return shallow<Filter>(
<Filter
onQueryChange={jest.fn()}
options={[1, 2, 3]}
property="foo"
- query={{}}
renderOption={option => option}
- {...props}
+ {...overrides}
/>
);
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx
index 38608957ba3..6d3ccf1ad84 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx
@@ -22,9 +22,7 @@ import * as React from 'react';
import IssuesFilter from '../IssuesFilter';
it('renders', () => {
- const wrapper = shallow(
- <IssuesFilter name="bugs" onQueryChange={jest.fn()} property="bugs" query={{}} />
- );
+ const wrapper = shallow(<IssuesFilter name="bugs" onQueryChange={jest.fn()} property="bugs" />);
expect(wrapper).toMatchSnapshot();
const renderOption = wrapper.prop('renderOption');
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx
index dc4c182f99b..1d5c8a0d3f0 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx
@@ -22,5 +22,5 @@ import * as React from 'react';
import MaintainabilityFilter from '../MaintainabilityFilter';
it('renders', () => {
- expect(shallow(<MaintainabilityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot();
+ expect(shallow(<MaintainabilityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx
index 811300cb54d..d23c0d049bf 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx
@@ -22,5 +22,5 @@ import * as React from 'react';
import NewCoverageFilter from '../NewCoverageFilter';
it('renders', () => {
- expect(shallow(<NewCoverageFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot();
+ expect(shallow(<NewCoverageFilter onQueryChange={jest.fn()} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx
index bca7edaf6aa..7e3f9c456eb 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx
@@ -22,5 +22,5 @@ import * as React from 'react';
import NewDuplicationsFilter from '../NewDuplicationsFilter';
it('renders', () => {
- expect(shallow(<NewDuplicationsFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot();
+ expect(shallow(<NewDuplicationsFilter onQueryChange={jest.fn()} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx
index f6b78344090..1afeb0dfe50 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx
@@ -22,7 +22,7 @@ import * as React from 'react';
import NewLinesFilter from '../NewLinesFilter';
it('renders', () => {
- const wrapper = shallow(<NewLinesFilter onQueryChange={jest.fn()} query={{}} />);
+ const wrapper = shallow(<NewLinesFilter onQueryChange={jest.fn()} />);
expect(wrapper).toMatchSnapshot();
const renderOption = wrapper.prop('renderOption');
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx
index fb8474f0a02..e93f0e37abd 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx
@@ -22,7 +22,5 @@ import * as React from 'react';
import NewMaintainabilityFilter from '../NewMaintainabilityFilter';
it('renders', () => {
- expect(
- shallow(<NewMaintainabilityFilter onQueryChange={jest.fn()} query={{}} />)
- ).toMatchSnapshot();
+ expect(shallow(<NewMaintainabilityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx
index 8ceb711739f..c415d02831a 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx
@@ -22,5 +22,5 @@ import * as React from 'react';
import NewReliabilityFilter from '../NewReliabilityFilter';
it('renders', () => {
- expect(shallow(<NewReliabilityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot();
+ expect(shallow(<NewReliabilityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx
index 99bb0d94389..08fce4a26bf 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx
@@ -22,5 +22,5 @@ import * as React from 'react';
import NewSecurityFilter from '../NewSecurityFilter';
it('renders', () => {
- expect(shallow(<NewSecurityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot();
+ expect(shallow(<NewSecurityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualifierFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualifierFilter-test.tsx
new file mode 100644
index 00000000000..b0797968910
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualifierFilter-test.tsx
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { shallow } from 'enzyme';
+import * as React from 'react';
+import { ComponentQualifier } from '../../../../types/component';
+import Filter from '../Filter';
+import QualifierFilter, { QualifierFilterProps } from '../QualifierFilter';
+
+it('renders', () => {
+ const wrapper = shallowRender();
+ expect(wrapper).toMatchSnapshot();
+
+ const { renderOption } = wrapper.find(Filter).props();
+ expect(renderOption(ComponentQualifier.Application, false)).toMatchSnapshot(
+ 'renderOption result'
+ );
+});
+
+function shallowRender(props: Partial<QualifierFilterProps> = {}) {
+ return shallow(<QualifierFilter onQueryChange={jest.fn()} value={undefined} {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx
index 756a3eac786..6ff157649a1 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx
@@ -38,5 +38,5 @@ it('should render with warning facet', () => {
});
function shallowRender(props: Partial<Props> = {}) {
- return shallow(<QualityGateFilter onQueryChange={jest.fn()} query={{}} {...props} />);
+ return shallow(<QualityGateFilter onQueryChange={jest.fn()} {...props} />);
}
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx
index 8232d5cb3b5..005e070025e 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx
@@ -22,5 +22,5 @@ import * as React from 'react';
import ReliabilityFilter from '../ReliabilityFilter';
it('renders', () => {
- expect(shallow(<ReliabilityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot();
+ expect(shallow(<ReliabilityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx
index 56f7d0e9915..387a7ba895f 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx
@@ -22,5 +22,5 @@ import * as React from 'react';
import SecurityFilter from '../SecurityFilter';
it('renders', () => {
- expect(shallow(<SecurityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot();
+ expect(shallow(<SecurityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx
index ecd7cc0995d..568c522000a 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx
@@ -22,7 +22,7 @@ import * as React from 'react';
import SecurityReviewFilter from '../SecurityReviewFilter';
it('renders', () => {
- const wrapper = shallow(<SecurityReviewFilter onQueryChange={jest.fn()} query={{}} />);
+ const wrapper = shallow(<SecurityReviewFilter onQueryChange={jest.fn()} />);
expect(wrapper).toMatchSnapshot();
const renderOption = wrapper.prop('renderOption');
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx
index 37b42810cd8..c7462eb6d63 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx
@@ -22,7 +22,7 @@ import * as React from 'react';
import SizeFilter from '../SizeFilter';
it('renders', () => {
- const wrapper = shallow(<SizeFilter onQueryChange={jest.fn()} query={{}} />);
+ const wrapper = shallow(<SizeFilter onQueryChange={jest.fn()} />);
expect(wrapper).toMatchSnapshot();
const renderOption = wrapper.prop('renderOption');
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap
index 9ce9bc4f614..9c45a22ef8e 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap
@@ -22,7 +22,6 @@ exports[`renders 1`] = `
]
}
property="coverage"
- query={Object {}}
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap
index 2c3c409178a..a0c1acb0b3c 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap
@@ -22,7 +22,6 @@ exports[`renders 1`] = `
]
}
property="duplications"
- query={Object {}}
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap
index 25be3053bcd..518429562a1 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap
@@ -19,7 +19,6 @@ exports[`renders 1`] = `
]
}
property="bugs"
- query={Object {}}
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap
index 250afc75ced..c366f8e6858 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap
@@ -53,14 +53,6 @@ exports[`should render the languages facet with the selected languages 1`] = `
]
}
property="languages"
- query={
- Object {
- "languages": Array [
- "java",
- "cs",
- ],
- }
- }
renderOption={[Function]}
value={
Array [
@@ -242,11 +234,6 @@ exports[`should render the languages without the ones in the facet 1`] = `
]
}
property="languages"
- query={
- Object {
- "languages": null,
- }
- }
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap
index 5a3cec2fbff..74c863bc426 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap
@@ -17,6 +17,5 @@ exports[`renders 1`] = `
name="Maintainability"
onQueryChange={[MockFunction]}
property="maintainability"
- query={Object {}}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap
index 11e95aab04c..893586a9cfc 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap
@@ -5,6 +5,5 @@ exports[`renders 1`] = `
className="leak-facet-box"
onQueryChange={[MockFunction]}
property="new_coverage"
- query={Object {}}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap
index 91a1620bb86..4fce695bb25 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap
@@ -5,6 +5,5 @@ exports[`renders 1`] = `
className="leak-facet-box"
onQueryChange={[MockFunction]}
property="new_duplications"
- query={Object {}}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap
index 1f04f9c5073..6d4b91aa8b8 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap
@@ -21,7 +21,6 @@ exports[`renders 1`] = `
]
}
property="new_lines"
- query={Object {}}
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap
index ff717a23c48..aee66f09413 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap
@@ -18,6 +18,5 @@ exports[`renders 1`] = `
name="Maintainability"
onQueryChange={[MockFunction]}
property="new_maintainability"
- query={Object {}}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap
index 33bac4a52fe..c2a1184a792 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap
@@ -18,6 +18,5 @@ exports[`renders 1`] = `
name="Reliability"
onQueryChange={[MockFunction]}
property="new_reliability"
- query={Object {}}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap
index 9c14c735545..ff165f6d2c7 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap
@@ -18,6 +18,5 @@ exports[`renders 1`] = `
name="Security"
onQueryChange={[MockFunction]}
property="new_security"
- query={Object {}}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap
new file mode 100644
index 00000000000..78a419e37a4
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap
@@ -0,0 +1,33 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders 1`] = `
+<Filter
+ header={
+ <FilterHeader
+ name="projects.facets.qualifier"
+ />
+ }
+ onQueryChange={[MockFunction]}
+ options={
+ Array [
+ "TRK",
+ "APP",
+ ]
+ }
+ property="qualifier"
+ renderOption={[Function]}
+/>
+`;
+
+exports[`renders: renderOption result 1`] = `
+<span
+ className="display-flex-center"
+>
+ <QualifierIcon
+ className="spacer-right"
+ fill="currentColor"
+ qualifier="APP"
+ />
+ qualifier.APP
+</span>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap
index 646483a9a19..f886d4bf11d 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap
@@ -15,7 +15,6 @@ exports[`renders 1`] = `
]
}
property="gate"
- query={Object {}}
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap
index db4d08b6663..355fccc7ef6 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap
@@ -17,6 +17,5 @@ exports[`renders 1`] = `
name="Reliability"
onQueryChange={[MockFunction]}
property="reliability"
- query={Object {}}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap
index b2fe4443191..9039e7ab671 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap
@@ -17,6 +17,5 @@ exports[`renders 1`] = `
name="Security"
onQueryChange={[MockFunction]}
property="security"
- query={Object {}}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap
index 1ca6b42af8d..d035ae827e5 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap
@@ -30,7 +30,6 @@ exports[`renders 1`] = `
]
}
property="security_review"
- query={Object {}}
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap
index f956104ccb9..a950d21b0d1 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap
@@ -20,7 +20,6 @@ exports[`renders 1`] = `
]
}
property="size"
- query={Object {}}
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap
index 39ca1365278..8c1830ec284 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap
@@ -86,14 +86,6 @@ exports[`should render maximum 10 tags in the searchbox results 1`] = `
]
}
property="tags"
- query={
- Object {
- "languages": Array [
- "java",
- "ad",
- ],
- }
- }
renderOption={[Function]}
value={
Array [
@@ -145,14 +137,6 @@ exports[`should render the tags facet with the selected tags 1`] = `
]
}
property="tags"
- query={
- Object {
- "tags": Array [
- "lang",
- "sonar",
- ],
- }
- }
renderOption={[Function]}
value={
Array [
@@ -292,11 +276,6 @@ exports[`should render the tags without the ones in the facet 1`] = `
]
}
property="tags"
- query={
- Object {
- "tags": null,
- }
- }
renderOption={[Function]}
/>
`;
@@ -354,11 +333,6 @@ exports[`should render the tags without the ones in the facet 2`] = `
]
}
property="tags"
- query={
- Object {
- "tags": null,
- }
- }
renderOption={[Function]}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/projects/query.ts b/server/sonar-web/src/main/js/apps/projects/query.ts
index e40e9c9af0c..727ca3439d2 100644
--- a/server/sonar-web/src/main/js/apps/projects/query.ts
+++ b/server/sonar-web/src/main/js/apps/projects/query.ts
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { ComponentQualifier } from '../../types/component';
import { VISUALIZATIONS } from './utils';
type Level = 'ERROR' | 'WARN' | 'OK';
@@ -38,6 +39,7 @@ export interface Query {
size?: number;
new_lines?: number;
languages?: string[];
+ qualifier?: ComponentQualifier;
tags?: string[];
search?: string;
sort?: string;
@@ -65,6 +67,7 @@ export function parseUrlQuery(urlQuery: T.RawQuery): Query {
new_lines: getAsNumericRating(urlQuery['new_lines']),
languages: getAsStringArray(urlQuery['languages']),
tags: getAsStringArray(urlQuery['tags']),
+ qualifier: getAsQualifier(urlQuery['qualifier']),
search: getAsString(urlQuery['search']),
sort: getAsString(urlQuery['sort']),
view: getView(urlQuery['view']),
@@ -106,7 +109,7 @@ export function convertToFilter(query: Query, isFavorite: boolean): string {
'new_maintainability'
].forEach(property => pushMetricToArray(query, property, conditions, convertIssuesRating));
- ['languages', 'tags'].forEach(property =>
+ ['languages', 'tags', 'qualifier'].forEach(property =>
pushMetricToArray(query, property, conditions, convertArrayMetric)
);
@@ -160,6 +163,10 @@ function getAsStringArray(value: any): string[] | undefined {
return value.split(',');
}
+function getAsQualifier(value: string | undefined): ComponentQualifier | undefined {
+ return value ? (value as ComponentQualifier) : undefined;
+}
+
function getView(value: any): string | undefined {
return typeof value !== 'string' || value === 'overall' ? undefined : value;
}
@@ -251,7 +258,8 @@ function mapPropertyToMetric(property?: string): string | undefined {
gate: 'alert_status',
languages: 'languages',
tags: 'tags',
- search: 'query'
+ search: 'query',
+ qualifier: 'qualifier'
};
return property && map[property];
}
diff --git a/server/sonar-web/src/main/js/apps/projects/utils.ts b/server/sonar-web/src/main/js/apps/projects/utils.ts
index 445c5119601..753a9c457d0 100644
--- a/server/sonar-web/src/main/js/apps/projects/utils.ts
+++ b/server/sonar-web/src/main/js/apps/projects/utils.ts
@@ -166,7 +166,8 @@ export const FACETS = [
'ncloc',
'alert_status',
'languages',
- 'tags'
+ 'tags',
+ 'qualifier'
];
export const LEAK_FACETS = [
@@ -179,7 +180,8 @@ export const LEAK_FACETS = [
'new_lines',
'alert_status',
'languages',
- 'tags'
+ 'tags',
+ 'qualifier'
];
const REVERSED_FACETS = ['coverage', 'new_coverage'];
@@ -333,7 +335,8 @@ const propertyToMetricMap: T.Dict<string | undefined> = {
gate: 'alert_status',
languages: 'languages',
tags: 'tags',
- search: 'query'
+ search: 'query',
+ qualifier: 'qualifier'
};
const metricToPropertyMap = invert(propertyToMetricMap);